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 ...
随机推荐
- qml: 打包 和 发布
Qt 提供了打包工具windeployqt, 利用该工具可以很方便的解决qt的依赖问题(注:通过实际验证,发现该工具只能解决大部分的依赖问题,不知道是不是本人 没有正确的使用的问题). qt源码编译r ...
- Bootstrap框架介绍
Bootstrap框架介绍 一.Bootstarp环境部署 1>.什么是Bootstartp框架 Bootstrap是Twitter开源的基于HTML.CSS.JavaScript的前端框架.它 ...
- Rancher之Pipeline JAVA demo
Rancher Pipeline Pipeline,简单来说,就是一套运行于Rancher上的工作流框架,将原本独立运行于单个或者多个节点的任务连接起来,实现单个任务难以完成的复杂发布流程. Ranc ...
- CentOS7 图形化方式安装 Oracle 18c 单实例
下载 Oracle 数据库,zip 包 https://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.h ...
- python Bootstarp框架和inconfont、font-awesome使用
http://www.bootcss.com/ http://www.runoob.com/bootstrap/bootstrap-panels.html 查找基本的没问题 https://www. ...
- Hadoop记录-安装ambari hdp集群
#!/bin/sh #配置用户sudo权限(参考/etc/sudoers文件,在/etc/sudoers.d/新建一个用户配置文件,注意要注销) #需要在/etc/sudoers末尾追加:sfapp ...
- STM32学习笔记:【003】GPIO
版本:STM32F429 Hal库v1.10 在STM32中,最常用到的功能莫过于GPIO(General Purpose Input Output .通用输入/输出)了,在STM32中,除了除去AD ...
- Mastering Markdown
What is markdown? Markdown is a lightweight and easy-to-use syntax for styling all forms writing on ...
- linux常用命令说明
1. 基础快捷键使用 ctrl + c:停止进程 ctrl + l:清屏 ctrl + r:搜索历史命令 ctrl + q:退出 2.常用目录或文件夹命令 说明:安装linux时,创建一个itcast ...
- 计算机网络--HTTP协议
TCP/IP协议 互联网构建的初衷是信息的共享.在信息的传递过程中,计算机不可避免的需要产生交流.就像我们与别人交谈需要懂得对方的语言才能明白对方表达的意思一样,计算机的交流也需要一个约束了,称之为协 ...