使用Netty搭建WebSocket服务器

1.WebSocketServer.java

public class WebSocketServer {
private final ChannelGroup group = new DefaultChannelGroup(ImmediateEventExecutor.INSTANCE); private final EventLoopGroup workerGroup = new NioEventLoopGroup(); private Channel channel; public ChannelFuture start(InetSocketAddress address) {
ServerBootstrap boot = new ServerBootstrap();
boot.group(workerGroup).channel(NioServerSocketChannel.class).childHandler(createInitializer(group)); ChannelFuture f = boot.bind(address).syncUninterruptibly();
channel = f.channel();
return f;
} protected ChannelHandler createInitializer(ChannelGroup group2) {
return new ChatServerInitializer(group2);
} public void destroy() {
if (channel != null)
channel.close();
group.close();
workerGroup.shutdownGracefully();
} public static void main(String[] args) {
final WebSocketServer server = new WebSocketServer();
ChannelFuture f = server.start(new InetSocketAddress());
System.out.println("server start................");
Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
server.destroy();
}
});
f.channel().closeFuture().syncUninterruptibly();
} private static WebSocketServer instance; private WebSocketServer() {} public static synchronized WebSocketServer getInstance() {// 懒汉,线程安全
if (instance == null) {
instance = new WebSocketServer();
}
return instance;
} public void running(){
if(instance != null){ String port=null;
port=BusinessConfigUtils.findProperty("websocket_port");//获取端口号
if(null==port||port.length()<||!StringUtils.isNumeric(port)){
port="";
}
instance.start(new InetSocketAddress(Integer.valueOf(port)));
//ChannelFuture f =
System.out.println("----------------------------------------WEBSOCKET SERVER START----------------------------------------");
/*Runtime.getRuntime().addShutdownHook(new Thread() {
@Override
public void run() {
instance.destroy();
}
});
f.channel().closeFuture().syncUninterruptibly();*/
}
}
}

2.ChatServerInitializer.java

public class ChatServerInitializer extends ChannelInitializer<Channel> {

	private final ChannelGroup group;
public ChatServerInitializer(ChannelGroup group) {
super();
this.group = group;
} @Override
protected void initChannel(Channel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new HttpServerCodec()); pipeline.addLast(new ChunkedWriteHandler()); pipeline.addLast(new HttpObjectAggregator(64*1024)); pipeline.addLast(new HttpRequestHandler("/ws")); pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); pipeline.addLast(new TextWebSocketFrameHandler(group)); } }

 3. HttpRequestHandler.java

public class HttpRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> {

	private LoginTimeService loginTimeService = SpringContextHolder.getBean("loginTimeServiceImpl");
private final String wsUri; public HttpRequestHandler(String wsUri) {
super();
this.wsUri = wsUri;
} @Override
@SuppressWarnings("deprecation")
protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
if (wsUri.equalsIgnoreCase(msg.getUri().substring(0, 3))) {
String userId = findUserIdByUri(msg.getUri());
if (userId != null && userId.trim() != null && userId.trim().length() > 0) {
ctx.channel().attr(AttributeKey.valueOf(ctx.channel().id().asShortText())).set(userId);// 写userid值
UserIdToWebSocketChannelShare.userIdToWebSocketChannelMap.put(userId, ctx.channel()); // 用户Id与Channel绑定
loginTimeService.onLine(userId, new Date());// 统计上线记录 } else {
}// 没有获取到用户Id
ctx.fireChannelRead(msg.setUri(wsUri).retain());
}
} private String findUserIdByUri(String uri) {// 通过Uid获取用户Id--uri中包含userId
String userId = "";
try {
userId = uri.substring(uri.indexOf("userId") + 7);
if (userId != null && userId.trim() != null && userId.trim().length() > 0) {
userId = userId.trim();
}
} catch (Exception e) {
}
return userId;
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
cause.printStackTrace(System.err);
}
}

 4. TextWebSocketFrameHandler.java

public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

	private LoginTimeService loginTimeService = SpringContextHolder.getBean("loginTimeServiceImpl");
private final ChannelGroup group; public TextWebSocketFrameHandler(ChannelGroup group) {
super();
this.group = group;
} @Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {
ctx.pipeline().remove(HttpRequestHandler.class);
// group.writeAndFlush("");
group.add(ctx.channel());
} else {
super.userEventTriggered(ctx, evt);
}
} @Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
group.writeAndFlush(msg.retain());
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
ctx.close();
cause.printStackTrace();
} @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception { // (6)
Channel incoming = ctx.channel();
String userId = (String) incoming.attr(AttributeKey.valueOf(incoming.id().asShortText())).get();
UserIdToWebSocketChannelShare.userIdToWebSocketChannelMap.remove(userId);// 删除缓存的通道
loginTimeService.outLine(userId, new Date());// 下线通过
} }

  

使用Netty做WebSocket服务端的更多相关文章

  1. Netty 搭建 WebSocket 服务端

    一.编码器.解码器 ... ... @Autowired private HttpRequestHandler httpRequestHandler; @Autowired private TextW ...

  2. Netty搭建WebSocket服务端

    Netty服务端 1.引入依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=& ...

  3. WebSocket服务端

    http://blog.csdn.net/qq_20282263/article/details/54310737 C# 实现WebSocket服务端 原创 2017年01月10日 09:22:50 ...

  4. asp.net网站作为websocket服务端的应用该如何写

    最近被websocket的一个问题困扰了很久,有一个需求是在web网站中搭建websocket服务.客户端通过网页与服务器建立连接,然后服务器根据ip给客户端网页发送信息. 其实,这个需求并不难,只是 ...

  5. C# WebSocket 服务端示例代码 + HTML5客户端示例代码

    WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System.Linq; using System. ...

  6. nodejs搭建简单的websocket服务端

    创建websocket服务端使用了nodejs-websocket ,首先要安装nodejs-websocket,在项目的目录下: npm install nodejs-websocket 1.搭建w ...

  7. 用nodejs快速实现websocket服务端(带SSL证书生成)

    有不少公司将nodejs的socket.io作为websocket的解决方案,很遗憾的是socket.io是对websocket的封装,并不支持html5原始的websocket协议,微信小程序使用的 ...

  8. VB6+Winsock编写的websocket服务端

    早就写好了,看这方面资料比较少,索性贴出来.只是一个DEMO中的,没有做优化,代码比较草.由于没地方上传附件,所以只把一些主要的代码贴出来. 这只是服务端,不过客户端可以反推出来,其实了解了webso ...

  9. .NET 即时通信,WebSocket服务端实例

    即时通信常用手段 1.第三方平台 谷歌.腾讯 环信等多如牛毛,其中谷歌即时通信是免费的,但免费就是免费的并不好用.其他的一些第三方一般收费的,使用要则限流(1s/限制x条消息)要么则限制用户数. 但稳 ...

随机推荐

  1. 最长上升子序列算法(n^2 及 nlogn) (LIS) POJ2533Longest Ordered Subsequence

    问题描述: 一个数的序列bi,当b1 < b2 < ... < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, ..., aN),我们可以得到一些上升的子序列 ...

  2. css 自定义滚动条

    我遇到的场景: 对于iframe窗口,自带滚动条是整个窗口的大小.有时需要顶部或底部固定,则滚动条不应该触碰到顶部或底部. 那么首先打开iframe时应该去掉滚动条 scrolling="n ...

  3. appium 底层原理

    appium的log详细分析http://blog.csdn.net/jffhy2017/article/details/69372064----------------------很多appium架 ...

  4. Pycharm 2018 1.2版本 Mac注册码激活码

    此链接中较为详细的解决了次问题:http://www.orsoon.com/Mac/159477.html

  5. css3有哪些新特性

    转载:http://blog.csdn.net/lxcao/article/details/52797914

  6. iClap专访:颠覆传统办公方式,规范化产品管理系统

    背景:DevStore是成立于2014年的移动互联网企业运营解决方案整合平台,线上资源涉及产品研发,设计,推广运维各个阶段,致力于为互联网从业者提供帮助.iClap是DevStore的全新产品,于20 ...

  7. Docker+.Net Core 的那些事儿-1.准备工作

    1.下载centos 地址:https://www.centos.org/download/ 我使用的是DVD ISO,这么做的目的是为了在之后的docker填坑的路上,方便使用centos中Fire ...

  8. Java:出现错误提示(java.sql.SQLException:Value '0000-00-00' can not be represented as java.sql.Date)

    Java:出现错误提示(java.sql.SQLException:Value '0000-00-00' can not be represented as java.sql.Date) 原因分析: ...

  9. Promise原理剖析

    传统的异步回调编程最大的缺陷是:回调地狱,由于业务逻辑非常复杂,代码串行请求好几层:并行请求以前也要通过引用step.async库实现.现在ES6推出了Promise,通过Promise的链式调用可以 ...

  10. mouseleave mouseout时候悬浮框不应该消失的时候消失了 css 解决办法

    要实现的效果和代码思路 简单来说就是 用一个div包着喇叭和悬浮框 悬浮事件写在这个div上 鼠标悬浮到div上的时候 悬浮框出现 最终要做成鼠标从小喇叭移动到下面的框上的时候 下面框是不会消失的. ...