使用Netty做WebSocket服务端
使用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服务端的更多相关文章
- Netty 搭建 WebSocket 服务端
一.编码器.解码器 ... ... @Autowired private HttpRequestHandler httpRequestHandler; @Autowired private TextW ...
- Netty搭建WebSocket服务端
Netty服务端 1.引入依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns=& ...
- WebSocket服务端
http://blog.csdn.net/qq_20282263/article/details/54310737 C# 实现WebSocket服务端 原创 2017年01月10日 09:22:50 ...
- asp.net网站作为websocket服务端的应用该如何写
最近被websocket的一个问题困扰了很久,有一个需求是在web网站中搭建websocket服务.客户端通过网页与服务器建立连接,然后服务器根据ip给客户端网页发送信息. 其实,这个需求并不难,只是 ...
- C# WebSocket 服务端示例代码 + HTML5客户端示例代码
WebSocket服务端 C#示例代码 using System; using System.Collections.Generic; using System.Linq; using System. ...
- nodejs搭建简单的websocket服务端
创建websocket服务端使用了nodejs-websocket ,首先要安装nodejs-websocket,在项目的目录下: npm install nodejs-websocket 1.搭建w ...
- 用nodejs快速实现websocket服务端(带SSL证书生成)
有不少公司将nodejs的socket.io作为websocket的解决方案,很遗憾的是socket.io是对websocket的封装,并不支持html5原始的websocket协议,微信小程序使用的 ...
- VB6+Winsock编写的websocket服务端
早就写好了,看这方面资料比较少,索性贴出来.只是一个DEMO中的,没有做优化,代码比较草.由于没地方上传附件,所以只把一些主要的代码贴出来. 这只是服务端,不过客户端可以反推出来,其实了解了webso ...
- .NET 即时通信,WebSocket服务端实例
即时通信常用手段 1.第三方平台 谷歌.腾讯 环信等多如牛毛,其中谷歌即时通信是免费的,但免费就是免费的并不好用.其他的一些第三方一般收费的,使用要则限流(1s/限制x条消息)要么则限制用户数. 但稳 ...
随机推荐
- 20165324 《Java程序设计》第3周学习总结
20165324 <Java程序设计>第3周学习总结 教材学习内容总结 本周学习内容如下: 编程语言思想 面向过程语言的核心是编写解决某个问题的代码块:在面向对象语言中,最核心的内容是对象 ...
- C++学习笔记--名称空间
名称空间是为了更好的控制名称的作用域,以管理不同的类库,避免发生冲突. 1.创建名称空间 如下,使用namespace关键字创建了pers和debts两个名称空间. #ifndef NAMESP_H_ ...
- Selenium2.0 Webdriver 随笔
Webdriver can't action the element when the element is out of view 1. Scroll to the element use Java ...
- DEPHI XE5 XE6 ANDROID IOS开发的几点体会
DEPHI XE5 XE6 ANDROID IOS开发的几点体会 2014-09-04 20:48 1.不纠结于APK或者APP的大小.现在的客户端设备都很廉价,300元以上的新安卓设备都不在乎软件的 ...
- XDU 1032
#include<cstdio> typedef long long ll; ; ll feima(ll a,ll b) { ll c=; while(b) { ) c=c*a%mod; ...
- dubbo-admin 部署
上一章主要是谈到zookeeper的安装和部署 因为zookeeper只是一个黑框,我们无法看到是否存在了什么提供者或消费者,这时就要借助Dubbo-Admin管理平台来实时的查看,也可以通过这个平台 ...
- APP移动端开发html模板
移动端开发模板: 750的稿子除以75: <!DOCTYPE html> <html> <head> <meta charset="utf-8&qu ...
- appium服务关键字
关键字 描述 实例 automationName 你想使用的自动化测试引擎 Appium (默认) 或 Selendroid platformName 你要测试的手机操作系统 iOS, Android ...
- 【Android】WebView读取本地图片
背景 咱的博客园APP,是通过一个WebView来展示新闻的详情的.新闻必然是图文并茂的,无论是支持离线缓存还是加速新闻的打开速度, 都需要咱们打通本地存储与WebView之间的桥梁. 思路 1:首先 ...
- Java并发编程之CountDownLatch的用法
一.含义 CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能.CountDownLatch是一个同步的辅助类,它可以允许一个或多个线程等待, ...