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 ...
随机推荐
- sys用户的操作
oracle中查找某个表属于哪个用户? select owner from dba_tables where table_name=upper('t_l_tradelist' ) 1 ...
- Go多组Raft库
Go多组Raft库 https://github.com/lni/dragonboat/blob/master/README.CHS.md 使用用例 https://github.com/lni/dr ...
- SpringBoot实战一:发送邮件
目录 邮件协议 引入邮件包 创建邮件类和测试类,写yml文件 文本邮件,HTML邮件,附件邮件,图片邮件 模板邮件 异常处理 来进行一个SpringBoot项目的实战,发送一下邮件,这里我们先了解一下 ...
- powershell 中常用cmd,unix命令(get-alias)
powershell 中常用cmd,unix命令(get-alias) Get-Content Alias cat -> Get-Content Alias gc -> Get-Conte ...
- xml实体注入学习
好久没学习技术了 很多东西都忘了 复习一下 测试代码 <?php $xml = file_get_contents("php://input"); $data = sim ...
- 搭建idea下的vue工程
需要先安装好nodejs和npm 输入下面的命令查看是否成功安装 node -v npm -v 一.开始 工作目录:IdeaProjects使用idea新建Static Web项目:demo 在dem ...
- Sliverlight常见错误集锦
1. 使用GridSplitter时候(参考),出现如下错误 C# 中的错误Error 2 The type 'sp:GridSplitter' was not found. Verify…… 对程序 ...
- ubuntu没有/usr/include/sys目录
实际上不是没有sys目录,只是系统给换路径了 32位系统:/usr/incude/i386-linux-gnu/sys 64位系统:/usr/include/x86_64-linux-gnu/sys/ ...
- 二十四、Linux 进程与信号---wait 函数
24.1 wait 函数说明 24.1.1 waitpid---等待子进程中断或结束 waitpid(等待子进程中断或结束) 相关函数 wait,fork #include <sys/types ...
- 【LDAP】LDAP注入漏洞与防御
0x01 前言 前两天爆了一个LDAP漏洞,据说存在了8年现在才被发现,感概一下,不知这8年来有多少站被搞了... 想着复现这个漏洞,就先复习一下LDAP注入的相关知识吧,差了很多资料,记一下笔记. ...