Нетти. Написать на канал вне обработчика - PullRequest
0 голосов
/ 19 мая 2019

есть способ записи в канал вне обработчика событий. Я хочу написать в канал строку, которую я печатаю в консоли. Это возможно?

fun main() {
    //Bootstrapping
    val eventLoopGroup = NioEventLoopGroup()
    val serverBootstrap = ServerBootstrap()
    serverBootstrap.group(eventLoopGroup)
    serverBootstrap.channel(NioServerSocketChannel::class.java)
    serverBootstrap.localAddress(InetSocketAddress(9988))
    serverBootstrap.childHandler(object : ChannelInitializer<SocketChannel>() {
        override fun initChannel(channel: SocketChannel?) {
            channel?.pipeline()
                ?.addLast(StringEncoder(StandardCharsets.UTF_8))
                ?.addLast(StringDecoder(StandardCharsets.UTF_8))
                ?.addLast(RemoteKeyboardHandler())
        }
    })

    val ch = serverBootstrap.bind().sync().channel()
    while (true) {
        val input = readLine()
        val future = ch.writeAndFlush(input)
        future.addListener {
            println(it.isSuccess)
            println(it.cause())
        }
    }
}

Это мой код сервера. В обработчике я просто отправляю строку "Hello world" при подключении. Я получаю OperationNotSupportedException. Я обнаружил на SO, что я не могу писать на серверный канал. Может быть, в этом суть. Так что мне делать в этом случае?

Ответы [ 2 ]

1 голос
/ 19 мая 2019

Сначала, если все это будет полезно, если вы разместите здесь свой класс клиент / сервер.

Вы можете получить объект канала из начальной загрузки:

Channel channel = new Bootstrap()
                    .group(workerGroup)
                    .channel(NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline()
                                    .addLast(new StringEncoder())
                                    .addLast(new StringDecoder())
                                    .addLast(new YourChannelHandler();
                        }
                    }).connect(YourIp, YourPort).sync().channel();

.channel () возвращает канал, где вы можете использовать writeAndFlush и передавать строку

channel.writeAndFlush("Example Message");

Если вы хотите добавить консольный ввод, вы можете сделать это прямо ниже:

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;

public class Client {

    private static final boolean EPOLL = Epoll.isAvailable();
    private static final int PORT = 25112;
    private static final String HOST = "localhost";

    private Channel ch;

    private static Integer count;


    // instead you can use a method to start the client
    public Client() {
        EventLoopGroup workerGroup = (EPOLL) ? new EpollEventLoopGroup() : new NioEventLoopGroup();

        try {
            ch = new Bootstrap()
                    .group(workerGroup)
                    .channel((EPOLL) ? EpollSocketChannel.class : NioSocketChannel.class)
                    .handler(new ChannelInitializer<SocketChannel>() {

                        @Override
                        protected void initChannel(SocketChannel ch) {
                            ch.pipeline()
                                    .addLast(new StringEncoder(StandardCharsets.UTF_8))
                                    .addLast(new StringDecoder(StandardCharsets.UTF_8))
                                    .addLast(new ClientMessageHandler());
                        }
                    }).connect(HOST, PORT).sync().channel();


            // console input
            BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
            String line = "";

            while ((line = reader.readLine()) != null) {
                if (line.startsWith("!exit") || line.startsWith("!disconnect")) {
                    reader.close();
                    line = null;
                    ch.disconnect();
                    break;
                } else if (line.toCharArray().length == 0) {
                    continue;
                } else if (line.startsWith("!ping")) {
                    ch.writeAndFlush(String.valueOf(System.nanoTime()));
                    continue;
                }

                ch.writeAndFlush(line);
            }

            //runCommandPromptReading();
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        } finally {
            workerGroup.shutdownGracefully();
        }
    }

//    private void runCommandPromptReading() throws IOException {
//        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
//        String line = "";
//
//        while ((line = reader.readLine()) != null) {
//            if (line.startsWith("!exit") || line.startsWith("!disconnect")) {
//                reader.close();
//                line = null;
//                ch.disconnect();
//                break;
//            } else if (line.toCharArray().length == 0) {
//                continue;
//            } else if (line.startsWith("!ping")) {
//                ch.writeAndFlush(String.valueOf(System.nanoTime()));
//                continue;
//            }
//
//            ch.writeAndFlush(line);
//        }
}

Надеюсь, это то, что вы хотели

0 голосов
/ 20 мая 2019

запись в ServerChannel не поддерживается, поскольку socket просто принимает новые sockets. Вы хотите записать в child Channel, на который есть ссылка в вашем ChannelInitializer.

...