我正在尝试使用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服务器
绑定---- ----更新
我创建了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"> </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));
}
答案 0 :(得分:1)
Netty使用责任链设计模式,因此无论何时需要使用协议,您都需要在管道中创建适当的解码器/编码器。对于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还有许多关于如何执行此操作的链接信息。