在网络套接字编程中使用外部调用发送消息

时间:2014-04-08 06:10:36

标签: sockets netty

我是socket编程和Netty框架的新手。我试图修改Echo Server example,以便在收到消息后不立即从客户端发送消息,但是来自另一个线程的调用将触发客户端向服务器发送消息。

问题是,除非客户端从readChannel或MessageReceived或channelActive发送消息,否则服务器不会收到消息,这是使用参数(ChannelHandlerContext)指定服务器的位置。我无法找到一种方法来保存服务器通道并稍后重复发送消息。

这是我的客户端处理程序代码;

import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;

public class EchoClientHandler extends ChannelHandlerAdapter {

    ChannelHandlerContext server;

    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        this.server = ctx; 
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
       // ctx.write(msg);  //not
    }

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
       //ctx.flush();
    }
    public void externalcall(String msg) throws Exception {
        if(server!=null){
            server.writeAndFlush("[" + "] " + msg + '\n');
        }
    }
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        // Close the connection when an exception is raised.
        ctx.close();
    }
}

当Client创建处理程序时,它还会创建一个带有“SourceGenerator”对象的线程,该对象将处理程序作为参数,以便调用externalcall()方法。

    import io.netty.bootstrap.Bootstrap;
    import io.netty.channel.ChannelFuture;
    import io.netty.channel.ChannelInitializer;
    import io.netty.channel.ChannelOption;
    import io.netty.channel.EventLoopGroup;
    import io.netty.channel.nio.NioEventLoopGroup;
    import io.netty.channel.socket.SocketChannel;
    import io.netty.channel.socket.nio.NioSocketChannel;

    /**
     * Sends one message when a connection is open and echoes back any received
     * data to the server.  Simply put, the echo client initiates the ping-pong
     * traffic between the echo client and server by sending the first message to
     * the server.
     */
    public class EchoClient {

        private final String host;
        private final int port;

        public EchoClient(String host, int port, int firstMessageSize) {
            this.host = host;
            this.port = port;
        }
        public void run() throws Exception {
            // Configure the client.
            EventLoopGroup group = new NioEventLoopGroup();
            final EchoClientHandler x = new EchoClientHandler();
            SourceGenerator sg = new SourceGenerator(x);
            new Thread(sg).start();
            try {
                Bootstrap b = new Bootstrap();
                b.group(group)
                 .channel(NioSocketChannel.class)
                 .option(ChannelOption.TCP_NODELAY, true)
                 .handler(new ChannelInitializer<SocketChannel>() {
                     @Override
                     public void initChannel(SocketChannel ch) throws Exception {
                         ch.pipeline().addLast(x);
                     }
                 });

                // Start the client.
                ChannelFuture f = b.connect(host, port).sync();

                // Wait until the connection is closed.
                f.channel().closeFuture().sync();
            } finally {
                // Shut down the event loop to terminate all threads.
                group.shutdownGracefully();
            }
        }

        public static void main(String[] args) throws Exception {
            // Print usage if no argument is specified.
            if (args.length < 2 || args.length > 3) {
                System.err.println(
                        "Usage: " + EchoClient.class.getSimpleName() +
                        " <host> <port> [<first message size>]");
                return;
            }
            // Parse options.
            final String host = args[0];
            final int port = Integer.parseInt(args[1]);
            final int firstMessageSize;
            if (args.length == 3) {
                firstMessageSize = Integer.parseInt(args[2]);
            } else {
                firstMessageSize = 256;
            }

            new EchoClient(host, port, firstMessageSize).run();
        }
    }

和SourceGenerator类;

public class SourceGenerator implements Runnable {
    public String dat;
    public EchoClientHandler asd;
    public SourceGenerator(EchoClientHandler x) {
        asd = x;
        System.out.println("initialized source generator");
        dat = "";
    }

    @Override
    public void run() {
        try{
            while(true){
                Thread.sleep(2000);
                dat += "a"; 
                asd.externalcall(dat);
                System.out.print("ha!");
            }
        }catch(Exception e){
            e.printStackTrace();

        }
    }
}

提前致谢!

1 个答案:

答案 0 :(得分:1)

如果您想撰写String,则需要StringEncoder中的ChannelPipeline

否则您只能发送ByteBuf个实例。