java - 在浏览器中使用Netty将短信与websocket绑定(bind)

标签 java netty

我正在尝试使用 Netty 实现 websockets。我尝试了 DiscardServer 示例,如果我只是使用 Telnet 运行它,它就可以正常工作

  Telnet localhost 8090.

因此,无论我在终端窗口中输入什么消息,它都会返回给我。但现在我想在浏览器中实现相同的功能,就像如果我在文本区域中放置一些文本消息,那么它应该在浏览器上显示该文本消息。

我可以使用以下代码启动 websocket 服务器

    ChannelFactory factory = new NioServerSocketChannelFactory(
            Executors.newCachedThreadPool(),
            Executors.newCachedThreadPool());

    ServerBootstrap bootstrap = new ServerBootstrap(factory);

    bootstrap.setPipelineFactory(new ChannelPipelineFactory() {
        public ChannelPipeline getPipeline() {
            return Channels.pipeline(new DiscardServerHandler());
        }
    });

    bootstrap.setOption("child.tcpNoDelay", true);
    bootstrap.setOption("child.keepAlive", true);

    bootstrap.bind(new InetSocketAddress(8090));

但是如何将我的文本区域中的短信与 websocket 服务器绑定(bind)

----已更新----

我已经创建了 MyServerHandler 类

   public class MyServerHandler extends SimpleChannelUpstreamHandler {

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
    Object msg = e.getMessage();        
    //msg.getClass();
    if (msg instanceof HttpRequest) {
                    //handleHttpRequest(ctx, (HttpRequest) msg);
        ctx.getChannel().write(msg);
    } else if (msg instanceof WebSocketFrame) {
        //handleWebSocketFrame(ctx, (WebSocketFrame) msg);
    }

}
  }

它调用messageReceived方法,但不执行任何if条件。

我还写了WebSocketServerPipelineFactory类

   public class WebSocketServerPipelineFactory implements ChannelPipelineFactory {

@Override
    public ChannelPipeline getPipeline() throws Exception {
        // Create a default pipeline implementation.
        ChannelPipeline pipeline = pipeline();
        pipeline.addLast("decoder", new HttpRequestDecoder());
        pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
        pipeline.addLast("encoder", new HttpResponseEncoder());
        pipeline.addLast("handler", new MyServerHandler());
        return pipeline;
    }
    }

我认为它也没有调用此类的方法。

在我写的jsp文件中

   <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"  type="text/javascript"></script>
   <script>
   var MESSAGE_HANDSHAKE = "handshake";
   var MESSAGE_OPPONENT_UPDATE = "response";
   var MESSAGE_TURN_INDICATOR = "turn";
   var MESSAGE_GAME_OVER = "game_over";
   var WEBSOCKET_URL = "ws://localhost:8090";
   $(document).ready(function() {
   ws = new WebSocket(WEBSOCKET_URL);

   ws.onopen = function(event) { 
 alert("test");
 $('#status').text("Waiting...."); 
  };

   ws.onmessage = function(event) {
    var message = jQuery.parseJSON(event.data);

    alert(message.type);
   }

   }); 

<body>
 <p id="status">&nbsp;</p>
</body>

它不会使用任何 jquery 方法。我还缺少什么吗?

另外,如果我写

  ws.send("Test Message");

它抛出以下java脚本错误

 Uncaught Error: INVALID_STATE_ERR: DOM Exception 11 login.htm:33
 (anonymous function) login.htm:33
 f.extend._Deferred.e.resolveWith jquery.min.js:2
 e.extend.ready jquery.min.js:2
 c.addEventListener.C

如果我使用

   var WEBSOCKET_URL = "wss://echo.websocket.org/";

然后它就可以工作了,所以这是我无法连接到我的服务器吗?

我正在使用 eclipse 来运行此代码。我正在使用 Apache Tomcat 运行 jsp 代码,并通过将 WebsocketServer.class 作为 java 应用程序运行来运行 websocket 服务器。这有什么区别吗?

---已更新---

我在 MyServerHandler 类中编写了以下方法,并在浏览器中收到错误

 Error during WebSocket handshake: 'Sec-WebSocket-Accept' header is missing 

MySeverHandler.java

  private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req)
        throws Exception {

    // Allow only GET methods.
    if (req.getMethod() != HttpMethod.GET) {
    //  sendHttpResponse(ctx, req, new DefaultHttpResponse(
        //      HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN));
        return;
    }

    // Serve the WebSocket handshake request.
    if (req.getUri().equals(WEBSOCKET_PATH)
            && Values.UPGRADE.equalsIgnoreCase(req.getHeader(CONNECTION))
            && WEBSOCKET.equalsIgnoreCase(req.getHeader(Names.UPGRADE))) {

        // Create the WebSocket handshake response.
        HttpResponse res = new DefaultHttpResponse(
                HTTP_1_1,
                new HttpResponseStatus(101, "Web Socket Protocol Handshake"));
        res.addHeader(Names.UPGRADE, WEBSOCKET);
        res.addHeader(CONNECTION, Values.UPGRADE);


        // Upgrade the connection and send the handshake response.
        ChannelPipeline p = ctx.getChannel().getPipeline();
        p.remove("aggregator");
        p.replace("decoder", "wsdecoder", new WebSocketFrameDecoder());

        // Write handshake response to the channel
        ctx.getChannel().write(res);

        // Upgrade encoder to WebSocketFrameEncoder
        p.replace("encoder", "wsencoder", new WebSocketFrameEncoder());

        // Initialize the game. Assign players to a game and assign them a letter (X or O)
        ///initGame(ctx);

        return;
    }

    // Send an error page otherwise.
    sendHttpResponse(ctx, req, new DefaultHttpResponse(
            HttpVersion.HTTP_1_1, HttpResponseStatus.FORBIDDEN));
}

最佳答案

Netty 使用责任链设计模式,因此每当您需要使用协议(protocol)时,您都需要在管道中创建适当的解码器/编码器。对于 websocket,这里是一个示例管道。

public class WebSocketServerPipelineFactory implements ChannelPipelineFactory {
    public ChannelPipeline getPipeline() throws Exception {
            // Create a default pipeline implementation.
            ChannelPipeline pipeline = pipeline();
            pipeline.addLast("decoder", new HttpRequestDecoder());
            pipeline.addLast("aggregator", new HttpChunkAggregator(65536));
            pipeline.addLast("encoder", new HttpResponseEncoder());
            pipeline.addLast("handler", new YourBusinessHandler());
            return pipeline;
    }

}

您可以在业务处理程序中编写任何业务逻辑。在这种情况下,您只需回显收到的内容,因此在此处理程序中它将类似于 channel.write(incomingMessage);

看看这个 tic-tac-toe game了解更多信息。 github 上还有很多关于如何执行此操作的链接信息。

关于java - 在浏览器中使用Netty将短信与websocket绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11971694/

相关文章:

java - netty-socketio 读取socket.io 数据吗?

java - 移动 arraylist 对象的动画

java - 配置失败: Method beforeTest requires 1 parameters but 0 were supplied in the @Configuration annotation

java - Netty解码错误

multithreading - 为什么 netty 每个套接字共享相同的线程进行读写?

java - Scala 中的非阻塞读取,无需框架

java - Netty NIO Udt 尝试给出错误,我无法在文档中找到答案

java - <?扩展 > Java 语法

java - Java 的 QP 求解器

java - 获取键盘输入并用于变量事件