1 全局保存websocket的通道  NettyConfig.java

public class NettyConfig {
public static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
}

2  WebsocketHandler.java  接收处理响应  客户端发来的消息

/**
* 接收处理响应客户端处理 *
*/
public class WebsocketHandler extends SimpleChannelInboundHandler<Object>{
private WebSocketServerHandshaker handshaker;
private static final String WEB_SOCKET_URL = "ws://192.168.3.167:8888/websocket";
//客户端与服务端创建连接的时候调用
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
NettyConfig.group.add(ctx.channel());
System.out.println("客户端与服务端连接开启...");
} //客户端与服务端断开连接的时候调用
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
NettyConfig.group.remove(ctx.channel());
System.out.println("客户端与服务端连接关闭...");
} //服务端接收客户端发送过来的数据结束之后调用
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
} //工程出现异常的时候调用
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
} //服务端处理客户端websocket请求的核心方法
@Override
protected void messageReceived(ChannelHandlerContext context, Object msg) throws Exception {
//处理客户端向服务端发起http握手请求的业务
if (msg instanceof FullHttpRequest) {
handHttpRequest(context, (FullHttpRequest)msg);
}else if (msg instanceof WebSocketFrame) { //处理websocket连接业务
handWebsocketFrame(context, (WebSocketFrame)msg);
}
} /**
* 处理客户端与服务端之前的websocket业务
* @param ctx
* @param frame
*/
private void handWebsocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame){
//判断是否是关闭websocket的指令
if (frame instanceof CloseWebSocketFrame) {
handshaker.close(ctx.channel(), (CloseWebSocketFrame)frame.retain());
}
//判断是否是ping消息
if (frame instanceof PingWebSocketFrame) {
ctx.channel().write(new PongWebSocketFrame(frame.content().retain()));
return;
} //判断是否是二进制消息,如果是二进制消息,抛出异常
if( ! (frame instanceof TextWebSocketFrame) ){
System.out.println("目前我们不支持二进制消息");
throw new RuntimeException("【"+this.getClass().getName()+"】不支持消息");
}
//返回应答消息
//获取客户端向服务端发送的消息
String request = ((TextWebSocketFrame) frame).text();
System.out.println("服务端收到客户端的消息====>>>" + request);
TextWebSocketFrame tws = new TextWebSocketFrame(new Date().toString()
+ request);
//群发,服务端向每个连接上来的客户端群发消息
//NettyConfig.group.writeAndFlush(tws); //单发 发给莫个人
NettyConfig.group.find(ctx.channel().id()).writeAndFlush(tws); }
/**
* 处理客户端向服务端发起http握手请求的业务
* @param ctx
* @param req
*/
private void handHttpRequest(ChannelHandlerContext ctx, FullHttpRequest req){
if (!req.getDecoderResult().isSuccess()
|| ! ("websocket".equals(req.headers().get("Upgrade")))) {
sendHttpResponse(ctx, req,
new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.BAD_REQUEST));
return;
}
WebSocketServerHandshakerFactory wsFactory = new WebSocketServerHandshakerFactory(
WEB_SOCKET_URL, null, false);
handshaker = wsFactory.newHandshaker(req);
if (handshaker == null) {
WebSocketServerHandshakerFactory.sendUnsupportedWebSocketVersionResponse(ctx.channel());
}else{
handshaker.handshake(ctx.channel(), req);
}
} /**
* 服务端向客户端响应消息
* @param ctx
* @param req
* @param res
*/
private void sendHttpResponse(ChannelHandlerContext ctx, FullHttpRequest req,
DefaultFullHttpResponse res){
if (res.getStatus().code() != 200) {
ByteBuf buf = Unpooled.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8);
res.content().writeBytes(buf);
buf.release();
}
//服务端向客户端发送数据
ChannelFuture f = ctx.channel().writeAndFlush(res);
if (res.getStatus().code() != 200) {
f.addListener(ChannelFutureListener.CLOSE);
}
} }

3  初始化连接时候的各个组件  

**
* 初始化连接时候的各个组件 *
*/
public class MyWebSocketChannelHandler extends ChannelInitializer<SocketChannel> { @Override
protected void initChannel(SocketChannel e) throws Exception {
e.pipeline().addLast("http-codec", new HttpServerCodec());
e.pipeline().addLast("aggregator", new HttpObjectAggregator(65536));
e.pipeline().addLast("http-chunked", new ChunkedWriteHandler());
e.pipeline().addLast("handler", new WebsocketHandler());
} }

4 启动服务

/**
* 程序的入口,负责启动应用
*
*/
public class Main {
public static void main(String[] args) {
EventLoopGroup bossGroup = new NioEventLoopGroup();
EventLoopGroup workGroup = new NioEventLoopGroup();
try {
ServerBootstrap b = new ServerBootstrap();
b.group(bossGroup, workGroup);
b.channel(NioServerSocketChannel.class);
b.childHandler(new MyWebSocketChannelHandler());
System.err.println("服务端开启等待客户端连接....");
Channel ch = b.bind(8888).sync().channel();
ch.closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}finally{
//优雅的退出程序
bossGroup.shutdownGracefully();
workGroup.shutdownGracefully();
}
}
}

 5 客户端连接服务

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset = utf-8"/>
<title>WebSocket客户端</title>
<script type="text/javascript">
var socket;
if(!window.WebSocket){
window.WebSocket = window.MozWebSocket;
} if(window.WebSocket){
socket = new WebSocket("ws://localhost:8888/websocket");
socket.onmessage = function(event){
var ta = document.getElementById('responseContent');
ta.value += event.data + "\r\n";
}; socket.onopen = function(event){
var ta = document.getElementById('responseContent');
ta.value = "你当前的浏览器支持WebSocket,请进行后续操作\r\n";
}; socket.onclose = function(event){
var ta = document.getElementById('responseContent');
ta.value = "";
ta.value = "WebSocket连接已经关闭\r\n";
};
}else{
alert("您的浏览器不支持WebSocket");
} function send(message){
if(!window.WebSocket){
return;
}
if(socket.readyState == WebSocket.OPEN){
socket.send(message);
}else{
alert("WebSocket连接没有建立成功!!");
}
}
</script>
</head>
<body>
<form onSubmit="return false;">
<input type = "text" name = "message" value = ""/>
<br/><br/>
<input type = "button" value = "发送WebSocket请求消息" onClick = "send(this.form.message.value)"/>
<hr color="red"/>
<h2>客户端接收到服务端返回的应答消息</h2>
<textarea id = "responseContent" style = "width:1024px; height:300px"></textarea>
</form>
</body>
</html>

 6 也可以用java连接websocket服务

/**
* java websocket客户端
*
*/
public class WebSocketClientTest { public static WebSocketClient client;
public static void main(String[] args) {
try {
client = new WebSocketClient(new URI("ws://192.168.3.167:8888/websocket"),new Draft_6455()) {
@Override
public void onOpen(ServerHandshake serverHandshake) {
System.err.println("握手成功");
}
@Override
public void onMessage(String msg) {
System.err.println("收到消息=========="+msg);
if(msg.equals("over")){
client.close();
} } @Override
public void onClose(int i, String s, boolean b) {
System.err.println("链接已关闭");
} @Override
public void onError(Exception e){
e.printStackTrace();
System.err.println("发生错误已关闭");
}
};
} catch (URISyntaxException e) {
e.printStackTrace();
}
client.connect();
System.err.println(client.getDraft());
while(!client.getReadyState().equals(WebSocket.READYSTATE.OPEN)){
System.err.println("正在连接...");
}
//连接成功,发送信息
client.send("哈喽,连接一下啊"); }
}

7 netty 和websocketclient依赖

<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>5.0.0.Alpha1</version>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.3.5</version>
</dependency>

8 感谢慕课网相关资源 

netty websocket的更多相关文章

  1. Netty WebSocket 开发

    代码: Server package netty.protocol.websocket.server; import io.netty.bootstrap.ServerBootstrap; impor ...

  2. Netty+WebSocket简单实现网页聊天

    基于Netty+WebSocket的网页聊天简单实现 一.pom依赖 <dependency>        <groupId>io.netty</groupId> ...

  3. Netty+WebSocket 获取火币交易所数据项目

    Netty+WebSocket 获取火币交易所时时数据项目 先附上项目项目GitHub地址 spring-boot-netty-websocket-huobi 项目简介 本项目使用 SpringBoo ...

  4. netty websocket协议开发

    websocket的好处我们就不用多说了,就是用于解决长连接.服务推送等需要的一种技术. 以下我们来看一个例子: package com.ming.netty.http.websocket; impo ...

  5. Spring+Netty+WebSocket实例

    比较贴近生产,详见注释 一.pom.xml 具体太长,详见源码 </dependency> <dependency> <groupId>io.netty</g ...

  6. SpringBoot+Netty+WebSocket实现实时通信

    这篇随笔暂时不讲原理,首先搭建起一个简单的可以实现通信的Demo.之后的一系列随笔会进行一些原理上的分享. 不过在这之前大家最好了解一下Netty的线程模型和NIO编程模型,会对它的整体逻辑有所了解. ...

  7. netty&websocket

    1.先判断是不是http 消息,不是返回400,是则remove之前添加的http组件,动态添加websocket组件 添加WebSocket Encoder和WebSocket Decoder之后, ...

  8. netty(4)高级篇-Websocket协议开发

    一.HTTP协议的弊端 将HTTP协议的主要弊端总结如下: (1) 半双工协议:可以在客户端和服务端2个方向上传输,但是不能同时传输.同一时刻,只能在一个方向上传输. (2) HTTP消息冗长:相比于 ...

  9. 基于netty的websocket例子

    nettyServer package com.atguigu.netty.websocket; import javax.annotation.PostConstruct; import org.s ...

随机推荐

  1. [LeetCode] 276. Paint Fence 粉刷篱笆

    There is a fence with n posts, each post can be painted with one of the k colors. You have to paint ...

  2. (二)主板BIOS设置与硬盘分区、调整

    1.主板BIOS设置 前提,你得有一台电脑,台式机或笔记本电脑都行. BIOS负责开机时对系统中各个硬件进行初始化设置和测试,以确保系统能正常工作,是电脑硬件与软件程序之间的一座桥梁. 电脑在开机启动 ...

  3. python+lego ev3的心得总结 随时更新

    一.连接方面 1.试了蓝牙连接,被电脑防火墙拒绝了很多次,很奇怪,明明都pin码都对上了,然后瞬间被踢开. 2.数据线直连,在一台win7上怎么试也不行,在另一台上自动上windows update上 ...

  4. RobotFramework与Jenkins集成后发送groovy报告(比别处多了用例作者信息)

    https://www.cnblogs.com/gcgc/p/10037891.html 这篇文章中最终的发送报告是这个样子,每天大家看到这封邮件后也不知道是不是自己的用例错误了,导致大家不积极回复邮 ...

  5. [计算机视觉][神经网络与深度学习]SSD安装及其训练教程

    SSD的安装 在home目录下,获取SSD的代码,下载完成后有一个caffe文件夹 git clone https://github.com/weiliu89/caffe.git cd caffe g ...

  6. 【转】Ubuntu环境搭建svn服务器

    记录一次使用Ubuntu环境搭建svn服务器的详细步骤 一.查看是否已经安装svn 命令:svn如果显示以下信息,说明已安装 二.卸载已安装的svn 命令:sudo apt-get remove -- ...

  7. js中引用类型Math一些常用的方法和属性

    js中有一种引用类型叫做Math,和Global属于单体内置对象,里面有一些非常常用的数学方法和数学常量 常用数学常量 Math.E; // 自然对数的底数Math.LN10 10的自然对数 Math ...

  8. Django django.core.exceptions.ImproperlyConfigured: WSGI application 'myblog.wsgi.application' could not be loaded; Error importing module.报错

    报错内容 django.core.exceptions.ImproperlyConfigured: WSGI application 'myblog.wsgi.application' could n ...

  9. CI中如何配置BootStrap

  10. [LOJ3086] [GXOI2019] 逼死强迫症

    题目链接 LOJ:https://loj.ac/problem/3086 洛谷:https://www.luogu.org/problemnew/show/P5303 Solution 显然不考虑\( ...