netty5的channel写回websocket数据时候,onmessage方法接收不到
handler处理如下
package com.amarky.websocket;
import org.apache.log4j.Logger;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
import io.netty.util.CharsetUtil;
/**
*
* @author AMARKY
* @date 2016年9月8日
* @Desc 处理WEBSOCKET的请求
*/
public class WebsocketServerHandler extends SimpleChannelInboundHandler<Object> {
private static final Logger logger = Logger.getLogger(WebsocketServerHandler.class.getName());
private WebSocketServerHandshaker handsharker;
/**
* 接受数据
*/
@Override
protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
// 如果是HTTP请求
if (msg instanceof FullHttpRequest) {
handleHttpRequest(ctx, (FullHttpRequest) msg);
}
// WEBSOCKET接入
else if (msg instanceof WebSocketFrame) {
handleWebSocketFrame(ctx, (WebSocketFrame) msg);
}
}
/**
* 数据处理完成后,刷新出去
*/
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
}
/**
* 处理HTTP请求
*
* @param ctx
* @param msg
*/
private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req) {
// 如果解码失败,返回异常
if (!req.getDecoderResult().isSuccess() || (!"websocket".equals(req.headers().get("Upgrade")))) {
sendHttpResponse(ctx, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
return;
}
// 构造握手相应
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
"ws://localhost:8080/websocket", null, Boolean.FALSE);
handsharker = wsFactory.newHandshaker(req);
if (handsharker == null) {
WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
} else {
handsharker.handshake(ctx.channel(), req);
}
}
/**
* 处理WEBSOCKET请求
*
* @param ctx
* @param frame
*/
private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {
// 判断链路是否关闭
if (frame instanceof CloseWebSocketFrame) {
handsharker.close(ctx.channel(), (CloseWebSocketFrame) frame.retain());
return;
}
if (frame instanceof PingWebSocketFrame) {
new PongWebSocketFrame(frame.content().retain());
return;
}
// 只支持文本消息,不支持二进制消息
if (!(frame instanceof TextWebSocketFrame)) {
throw new UnsupportedOperationException(
String.format("%s frame type not supported", frame.getClass().getName()));
}
String request = ((TextWebSocketFrame) frame).text();
logger.info(String.format("%s received %s", ctx.channel(), request));
System.out.println(String.format("%s received %s", ctx.channel(), request));
// ctx.channel().write(new TextWebSocketFrame(request + " , 欢迎使用netty
// websocket 服务,现在时刻是: ")
// + new java.util.Date().toString());
ctx.channel().writeAndFlush("欢迎使用netty websocket 服务,现在时刻是: " + new java.util.Date().toString());
}
/**
* 返回请求
*
* @param ctx
* @param req
* @param defaultFullHttpResponse
*/
private void sendHttpResponse(ChannelHandlerContext ctx, DefaultFullHttpResponse res) {
// 返回应答的消息
if (res.getStatus().code() != 200) {
ByteBuf byteBuf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8);
res.content().writeBytes(byteBuf);
byteBuf.release();
HttpHeaders.setContentLength(res, res.content().readableBytes());
}
ChannelFuture f = ctx.channel().writeAndFlush(res);
if (!HttpHeaders.isKeepAlive(res) || res.getStatus().code() != 200) {
f.addListener(ChannelFutureListener.CLOSE);
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
}
}
websocket如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>netty 测试</title>
</head>
<body>
<script type="text/javascript">
var socket;
alert(window.WebSocket);
if(!window.WebSocket){
window.WebSocket = window.MozWebSocket;
}
if(window.WebSocket){
socket = new WebSocket("ws://localhost:8080/websocket");
socket.onopen = function(event){
var ta = document.getElementById('responseText');
ta.value = "打开websocket服务正常,支持websocket服务";
};
socket.onmessage = function(event){
var ta = document.getElementById('responseText');
ta.value = "";
ta.value = event.data;
};
socket.onclose = function(event){
var ta = document.getElementById('responseText');
ta.value = "";
ta.value = "websocket关闭";
};
}
else{
alert("不支持websocket");
}
function send(message){
if(!window.WebSocket){return;}
if(socket.readyState == WebSocket.OPEN){
socket.send(message);
}else{
alert("链接没成功");
}
}
</script>
<form onsubmit="return false;">
<input type = "text" name = "message" value = "netty实践" />
<br><br>
<input type = "button" value = "发送" onclick="send(this.form.message.value)" />
<hr color="bule" />
<h3>服务端应答消息</h3>
<textarea id = "responseText" style = "width: 500px;height: 300px"></textarea>
</form>
</body>
</html>
socket.onmessage方法接受不到writeAndFlush写回的数据,不知道是什么原因
- 点赞
- 写回答
- 关注问题
- 收藏
- 复制链接分享
- 邀请回答
1条回答
为你推荐
- java netty与c++使用socket tcp协议通信,c++作为客户端,java作为服务端使用的是netty,接收字节数据,先将字节转16进制字符串再转为普通字符串,中英文全出现乱码。求急大神,谢谢!
- java
- maven
- intellij-idea
- 5个回答
- 为什么它在超时时直接关闭连接而不是调用closeHandler方法?
- websocket
- 1个回答
- vue前端websocket连接不上springboot,报错Connection closed before receiving a handshake response
- java
- vue.js
- 1个回答
- 使用netty5,收消息和发消息是同一个线程吗
- java
- 4个回答
- springboot、netty、redis
- 开发语言
- 1个回答
- SpringBoot RedisTemplate打包后找不到类
- spring
- redis
- 3个回答
- 需求: MQ+ netty 做 集群推送服务
- java
- 1个回答
- netty ChannelOption 中的这几个常量什么作用?
- java
- java-ee
- eclipse
- intellij-idea
- 1个回答
- 请大神解答一下关于netty客户端定时发送消息给服务端
- java
- java-ee
- 2个回答
- netty4,异常断线的问题.
- nio
- socket
- netty
- 0个回答
- netty 接收16进制数据乱码
- netty 16进制数据乱码
- 3个回答
- 求助:netty 4.x服务器端出现CLOSE_WAIT的问题
- close_wait
- 服务端
- tcp
- java
- net
- 2个回答
- netty的channelRead方法是单线程调用还是多线程调用
- 并发
- 多线程
- net
- 2个回答
- netty消息转发中client端循环推送的问题
- java
- net
- 1个回答
- Netty-SocketIO启动报错
- java
- 1个回答
- 对于netty中sync()方法的一些疑问~
- socket
- java-ee
- websocket
- net
- 1个回答
- netty消息主动推送 ,不使用channelActive事件
- net
- 1个回答
- WebSocket获取的登录用户的信息
- session
- websocket
- 7个回答
- netty5怎么同时监听多个端口
- net
- 1个回答
- WebSocket服务端发消息给客户端,浏览器收到消息就关闭了
- 服务端
- socket
- 浏览器
- eb ocket
- 11个回答