Netty实现简单WebSocket服务器
- 本文参考《Netty权威指南》
├── WebSocketServerHandler.java
├── WebSocketServer.java
└── wsclient.html
- package com.xh.netty.test11;
- import io.netty.bootstrap.ServerBootstrap;
- import io.netty.channel.Channel;
- import io.netty.channel.ChannelInitializer;
- import io.netty.channel.ChannelPipeline;
- import io.netty.channel.EventLoopGroup;
- import io.netty.channel.nio.NioEventLoopGroup;
- import io.netty.channel.socket.SocketChannel;
- import io.netty.channel.socket.nio.NioServerSocketChannel;
- import io.netty.handler.codec.http.HttpObjectAggregator;
- import io.netty.handler.codec.http.HttpServerCodec;
- import io.netty.handler.stream.ChunkedWriteHandler;
- /**
- * Created by root on 1/8/18.
- */
- public class WebSocketServer {
- public void run(int port) {
- EventLoopGroup bossGroup = new NioEventLoopGroup();
- EventLoopGroup workerGroup = new NioEventLoopGroup();
- try {
- ServerBootstrap b = new ServerBootstrap();
- b.group(bossGroup, workerGroup)
- .channel(NioServerSocketChannel.class)
- .childHandler(new ChannelInitializer<SocketChannel>() {
- protected void initChannel(SocketChannel socketChannel) throws Exception {
- ChannelPipeline pipeline = socketChannel.pipeline();
- pipeline.addLast("http-codec", new HttpServerCodec());
- pipeline.addLast("aggregator", new HttpObjectAggregator(65536));
- pipeline.addLast("http-chunked", new ChunkedWriteHandler());
- pipeline.addLast("handler", new WebSocketServerHandler());
- }
- });
- Channel ch = b.bind(port).sync().channel();
- System.out.println("websocketserver start port at " + port);
- ch.closeFuture().sync();
- } catch (InterruptedException e) {
- e.printStackTrace();
- } finally {
- bossGroup.shutdownGracefully();
- workerGroup.shutdownGracefully();
- }
- }
- public static void main(String[] args) {
- int port = 8080;
- if (args.length > 0) {
- port = Integer.valueOf(args[0]);
- }
- new WebSocketServer().run(port);
- }
- }
- package com.xh.netty.test11;
- 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.*;
- import io.netty.handler.codec.http.websocketx.*;
- import io.netty.util.CharsetUtil;
- import java.util.Date;
- import java.util.logging.Logger;
- import static io.netty.handler.codec.http.HttpHeaderUtil.isKeepAlive;
- import static io.netty.handler.codec.http.HttpHeaderUtil.setContentLength;
- /**
- * Created by root on 1/8/18.
- */
- public class WebSocketServerHandler extends SimpleChannelInboundHandler {
- private WebSocketServerHandshaker handshaker;
- @Override
- protected void messageReceived(ChannelHandlerContext ctx, Object msg) throws Exception {
- System.out.println(msg.toString());
- //http
- if (msg instanceof FullHttpRequest) {
- handleHttpRequest(ctx, (FullHttpRequest) msg);
- } else if (msg instanceof WebSocketFrame) {//websocket
- handleWebsocketFrame(ctx, (WebSocketFrame) msg);
- }
- }
- @Override
- public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
- ctx.flush();
- }
- @Override
- public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
- cause.printStackTrace();
- ctx.close();
- }
- private void handleWebsocketFrame(ChannelHandlerContext ctx, WebSocketFrame msg) {
- //关闭链路指令
- if (msg instanceof CloseWebSocketFrame) {
- handshaker.close(ctx.channel(), (CloseWebSocketFrame) msg.retain());
- return;
- }
- //PING 消息
- if (msg instanceof PingWebSocketFrame) {
- ctx.write(new PongWebSocketFrame(msg.content().retain()));
- return;
- }
- //非文本
- if (!(msg instanceof TextWebSocketFrame)) {
- throw new UnsupportedOperationException(String.format("%s frame type not support", msg.getClass().getName()));
- }
- //应答消息
- String requset = ((TextWebSocketFrame) msg).text();
- ctx.channel().write(new TextWebSocketFrame(requset + " >>>>Now is " + new Date().toString()));
- }
- private void handleHttpRequest(ChannelHandlerContext ctx, FullHttpRequest msg) {
- //HTTP 请异常
- if (!msg.decoderResult().isSuccess() || !"websocket".equals(msg.headers().get("Upgrade"))) {
- System.out.println(msg.decoderResult().isSuccess());
- System.out.println(msg.headers().get("Upgrade"));
- sendHttpResponse(ctx, msg, new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
- return;
- }
- //握手
- WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory("ws://localhost:8080/websocket", null, false);
- handshaker = wsFactory.newHandshaker(msg);
- if (handshaker == null) {
- WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel());
- } else {
- handshaker.handshake(ctx.channel(), msg);
- }
- }
- private void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest msg, FullHttpResponse resp) {
- //响应
- if (resp.status().code() != 200) {
- ByteBuf buf = Unpooled.copiedBuffer(resp.status().toString(), CharsetUtil.UTF_8);
- resp.content().writeBytes(buf);
- buf.release();
- setContentLength(resp, resp.content().readableBytes());
- }
- //非Keep-Alive,关闭链接
- ChannelFuture future = ctx.channel().writeAndFlush(resp);
- if (!isKeepAlive(resp) || resp.status().code() != 200) {
- future.addListener(ChannelFutureListener.CLOSE);
- }
- }
- }
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Title</title>
- </head>
- <body>
- <form onsubmit="return false;">
- <input type="text" name="msg" value="NETTY">
- <button onclick="send(this.form.msg.value)">send</button>
- <br>
- <textarea id="resText">
- </textarea>
- </form>
- </body>
- <script>
- var socket;
- if (!window.WebSocket) {
- window.WebSocket = window.MozWebSocket;
- }
- if (window.WebSocket) {
- socket = new WebSocket("ws://127.0.0.1:8080/websocket");
- socket.onmessage = function (event) {
- var ta = document.getElementById("resText");
- ta.value = "";
- ta.value = event.data;
- };
- socket.onopen = function (event) {
- alert("浏览器支持WebSocket");
- var ta = document.getElementById("resText");
- ta.value = "";
- ta.value = "浏览器支持WebSocket";
- };
- socket.onclose = function (event) {
- var ta = document.getElementById("resText");
- ta.value = "";
- ta.value = "关闭WebSocket";
- }
- } else {
- alert("浏览器不支持WebSocket");
- }
- function send(msg) {
- if (!window.WebSocket) {
- return;
- }
- if (socket.readyState == WebSocket.OPEN) {
- socket.send(msg);
- } else {
- alert("建立连接失败")
- }
- }
- </script>
- </html>
Netty实现简单WebSocket服务器的更多相关文章
- 一款基于Netty开发的WebSocket服务器
代码地址如下:http://www.demodashi.com/demo/13577.html 一款基于Netty开发的WebSocket服务器 这是一款基于Netty框架开发的服务端,通信协议为We ...
- Swoole学习(五)Swoole之简单WebSocket服务器的创建
环境:Centos6.4,PHP环境:PHP7 服务端代码 <?php //创建websocket服务器 $host = '0.0.0.0'; $port = ; $ws = new swool ...
- Netty实现简单HTTP服务器
netty package com.dxz.nettydemo.http; import java.io.UnsupportedEncodingException; import io.netty.b ...
- (二)基于Netty的高性能Websocket服务器(netty-websocket-spring-boot)
@toc Netty是一款基于NIO(Nonblocking I/O,非阻塞IO)开发的网络通信框架,对比于BIO(Blocking I/O,阻塞IO),他的并发性能得到了很大提高. 1.Netty为 ...
- Netty实现简单UDP服务器
本文参考<Netty权威指南> 文件列表: ├── ChineseProverbClientHandler.java ├── ChineseProverbClient.java ├── C ...
- netty中的websocket
使用WebSocket 协议来实现一个基于浏览器的聊天室应用程序,图12-1 说明了该应用程序的逻辑: (1)客户端发送一个消息:(2)该消息将被广播到所有其他连接的客户端. WebSocket 在从 ...
- netty系列之:使用netty搭建websocket服务器
目录 简介 netty中的websocket websocket的版本 FrameDecoder和FrameEncoder WebSocketServerHandshaker WebSocketFra ...
- 【Netty】(7)---搭建websocket服务器
[Netty](7)---搭建websocket服务器 说明:本篇博客是基于学习某网有关视频教学. 目的:创建一个websocket服务器,获取客户端传来的数据,同时向客户端发送数据 一.服务端 1. ...
- netty的简单的应用例子
一.简单的聊天室程序 public class ChatClient { public static void main(String[] args) throws InterruptedExcept ...
随机推荐
- pt-kill 用法记录
pt-kill 用法记录 # 参考资料Percona-Toolkit系列之pt-kill杀会话利器http://www.fordba.com/percona-toolkit-pt-kill.html ...
- springMVC的参数检验
先说应用场景,比如说前台传来一个参数,我们肯定得在后台判断一下,比如id不能为空了,电话号码不能少于11位了等等.如果在service层一个一个判断岂不是要累死个人.代码也不简洁,这时候我们肯定会想到 ...
- 15. 迭代器模式(Iterator Pattern)
动机(Motivate): 在软件构建过程中,集合对象内部结构常常变化各异.但对于这些集合对象,我们希望在不暴露其内部结构的同时,可以让外部客户代码透明地访问其中包含的元素;同时这种“透明遍历 ...
- Maccms8.x 命令执行漏洞分析
下载链接https://share.weiyun.com/23802397ed25681ad45c112bf34cc6db 首先打开Index.php $m = be('get','m'); m参数获 ...
- 原生JavaScript运动功能系列(四):多物体多值链式运动
原生JavaScript运动功能系列(一):运动功能剖析与匀速运动实现 原生JavaScript运动功能系列(二):缓冲运动 原生JavaScript运动功能系列(三):多物体多值运动 多物体多值链式 ...
- elasticsearch 通过HTTP RESTful API 操作数据
1.索引样例数据 下载样例数据集链接 下载后解压到ES的bin目录,然后加载到elasticsearch集群 curl -XPOST 127.0.0.1:9200/bank/account/_bulk ...
- HDU 1027(数字排列 STL)
题意是求 n 个数在全排列中的第 m 个序列. 直接用 stl 中的 next_permutation(a, a+n) (这个函数是求一段序列的下一个序列的) 代码如下: #include <b ...
- ArcGis 拓扑检查——狭长角锐角代码C#
中学的时候醉心于研究怎么“逃课”,大学的时候豁然开悟——最牛逼的逃课是准时准地儿去上每一课,却不知到老师讲的啥,“大隐隐于市”大概就是这境界吧. 用到才听说有“余弦定理”这么一个东西,遂感叹“白上了大 ...
- 解决 Android Device Monitor 常见问题
Ø 简介 什么是 Android Device Monitor,中文意思就是安卓设备监视器,用于管理安装设备(手机.模拟器)用的.下面列出 Android Device Monitor 常见的一些问 ...
- 高并发秒杀系统--mybatis整合技巧
mybatis实现DAO接口编码技巧 1.XML文件通过namespace命名空间关联接口类 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD ...