Netty学习——通过websocket编程实现基于长连接的双攻的通信
Netty学习(一)基于长连接的双攻的通信,通过websocket编程实现
效果图,客户端和服务器端建立起长连接,客户端发送请求,服务器端响应

但是目前缺少心跳,如果两个建立起来的连接,一个断网之后,另外一个是感知不到对方已经断掉的。以后使用心跳技术来进行连接检测
须知:
状态码101,代表 协议转换,从HTTP协议升级为WebSocket协议
HTTP协议,一般访问的时候:是 Http://localhost:8080/ws
WebSocket协议,访问的时候,需要是:ws://localhost:8080/ws

实现代码:
服务器端:
package com.dawa.netty.fifthexample; import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler; import java.net.InetSocketAddress; /**
* @Title: MyServer
* @Author: 大娃
* @Date: 2019/11/28 14:02
* @Description:
*/
public class MyServer {
public static void main(String[] args) throws Exception{
//定义一个线程组 , 事件循环组 。 异步的NIO , 就是一个死循环。
EventLoopGroup bossGroutp = new NioEventLoopGroup(); //不断的接受连接,但是不处理
EventLoopGroup workerGroup = new NioEventLoopGroup(); // 完成后续处理,把结果返回给客户端
try { //服务端,启动类
ServerBootstrap serverBootstrap = new ServerBootstrap();
//group方法,有两个参数的,有一个参数的
serverBootstrap.group(bossGroutp, workerGroup).channel(NioServerSocketChannel.class).handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new WebSocketChannelInitializer()); //字处理器,自己 定义的 ChannelFuture channelFuture = serverBootstrap.bind(new InetSocketAddress(8899)).sync();
channelFuture.channel().closeFuture().sync();
} finally {
//优雅关闭、
bossGroutp.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
}
package com.dawa.netty.fifthexample; import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler; /**
* @Title: WebSocketChannelInitializer
* @Author: 大娃
* @Date: 2019/11/28 14:06
* @Description:
*/
public class WebSocketChannelInitializer extends ChannelInitializer<SocketChannel> { @Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast(new HttpServerCodec());
pipeline.addLast(new ChunkedWriteHandler());//新的处理器 块
pipeline.addLast(new HttpObjectAggregator(8192)); //将分开的段,给聚合到一起,形成完整的HTTP响应。很重要的一个对象,在处理HTTP的时候
pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));
pipeline.addLast(new TextWebSocketFrameHandler());
}
}
package com.dawa.netty.fifthexample; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import java.time.LocalDateTime; /**
* @Title: TextWebSocketFrameHandler
* @Author: 大娃
* @Date: 2019/12/2 08:33
* @Description:
*/
public class TextWebSocketFrameHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { /**
*
* @param ctx 上下文对象
* @param msg //文本帧对象
* @throws Exception 抛异常
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
System.out.println("收到消息:"+msg.text());
ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器时间:"+ LocalDateTime.now() )); //不能直接传入 字符串.因为不同协议的规范不同,websocket要求要传回这种的对象
} @Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
System.out.println("handlerAdded:" + ctx.channel().id().asLongText());//每一个channel 都有一个唯一的id值与其对应
} @Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
System.out.println("HandlerRemoved:" + ctx.channel().id().asLongText());
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.channel().close();
}
}
客户端(使用HTML,JS来代替模拟客户端)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>websocket客户端</title>
</head>
<body>
<!-- -->
<script type="text/javascript">
//使用浏览器,进行websocket服务器端的访问
var socket;
if (window.WebSocket) {//判断浏览器是否支持websocket
socket = new WebSocket("ws:localhost:8899/ws"); //建立websocket连接
socket.onmessage = function (ev) { //如果socket收到消息,这个onmessage方法就会被回调
var ta = document.getElementById('responseText');
ta.value = ta.value + "\n" + ev.data;
}; socket.onopen=function (ev) {//当连接被打开的时候,执行的回调
var ta = document.getElementById('responseText');
ta.value = "连接开启!";
}; socket.onclose = function (ev) {
var ta = document.getElementById('responseText');
ta.value = ta.value + "\n" + "连接断开!";
};
} else {
alert("浏览器不支持Websocket")
} function send(message) {
if (!window.WebSocket) {
return;
}
if (socket.readyState === WebSocket.OPEN) {
socket.send(message);
} else {
alert("连接未开启");
}
}
</script> <!--客户端访问后台 websocket程序-->
<form action="" onsubmit="return false;">
<textarea name="message" style="width: 400px;height: 200px;"></textarea> <input type="button" value="发送数据" onclick="send(this.form.message.value)"> <h3>服务器端输出:</h3>
<textarea id="responseText" style="width: 400px;height: 300px;"></textarea>
<input type="button" onclick="javascript:document.getElementById('responseText').value='';" value="清空内容">
</form>
</body>
</html>
Netty学习——通过websocket编程实现基于长连接的双攻的通信的更多相关文章
- 京东的Netty实践,京麦TCP网关长连接容器架构
背景 早期京麦搭建 HTTP 和 TCP 长连接功能主要用于消息通知的推送,并未应用于 API 网关.随着逐步对 NIO 的深入学习和对 Netty 框架的了解,以及对系统通信稳定能力越来越高的要求, ...
- 分享一个基于长连接+长轮询+原生的JS及AJAX实现的多人在线即时交流聊天室
实现网页版的在线聊天室的方法有很多,在没有来到HTML5之前,常见的有:定时轮询.长连接+长轮询.基于第三方插件(如FLASH的Socket),而如果是HTML5,则比较简单,可以直接使用WebSoc ...
- comet基于HTTP长连接技术(java即时通信,推送技术详解)
服务器推送技术的基础思想是将浏览器主动查询信息改为服务器主动发送信息,服务器发送一批数据,浏览器显示消息,同时保证与服务器的连接,当服务器需要再一次的发送数据,浏览器显示数据并保持连接. comet基 ...
- 通过netty实现服务端与客户端的长连接通讯,及心跳检测。
基本思路:netty服务端通过一个Map保存所有连接上来的客户端SocketChannel,客户端的Id作为Map的key.每次服务器端如果要向某个客户端发送消息,只需根据ClientId取出对应的S ...
- python 之 网络编程(基于TCP协议的套接字通信操作)
第八章网络编程 8.1 基于TCP协议的套接字通信 服务端套接字函数 s.bind() 绑定(主机,端口号)到套接字 s.listen() 开始TCP监听 s.accept() 被动接受TCP客户的连 ...
- python socket 编程之三:长连接、短连接以及心跳
长连接:开启一个socket连接,收发完数据后,不立刻关闭连接,可以多次收发数据包. 短连接:开启一个socket连接,收发完数据后,立刻关闭连接. 心跳:长连接在没有数据通信时,定时发送数据包(心跳 ...
- Socket编程中的长连接、短链接以及心跳包机制详解
参考:http://blog.csdn.net/zdwzzu2006/article/details/7723738 一.定义 1.TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,se ...
- python socket 编程之三:长连接、短连接以及心跳(转药师Aric的文章)
长连接:开启一个socket连接,收发完数据后,不立刻关闭连接,可以多次收发数据包. 短连接:开启一个socket连接,收发完数据后,立刻关闭连接. 心跳:长连接在没有数据通信时,定时发送数据包(心跳 ...
- python 之 网络编程(基于UDP协议的套接字通信)
8.5 基于UDP协议的套接字通信 UDP协议:数据报协议 特点:无连接,一发对应一收,先启动哪一端都不会报错 优点:发送效率高,但有效传输的数据量最多为500bytes 缺点:不可靠:发送数据,无需 ...
随机推荐
- CSP2019游记
第一轮 Day 0 今天正好学校开运动会,就从开幕式开始翘,申请来机房训练. 早上六点多到了机房. 然后果不其然,运动会又下雨了(祈雨大会).机房冷的一批. 今天中午没有午休时间,去食堂吃个饭就直接来 ...
- python items和setdefault函数
items() dict = {'runoob': '菜鸟教程', 'google': 'Google 搜索'} print("Value : %s" % dict.setdefa ...
- mysql-清除binlog日志命令
记录一个清除MySQL里binlog日志的命令,可用在定时任务脚本里. 只保留1天前的日志: PURGE MASTER LOGS BEFORE DATE_SUB(CURRENT_DATE, INTER ...
- Android so 文件
要点 不同的 CPU 架构需要不同的 so 文件 NDK平台不是后向兼容的,而是前向兼容的. ABI 的概念,每一个 Cpu架构对应一个 ABI(Application Binary Interfac ...
- 最新JetBrains PyCharm 使用教程--创建或导入项目(二)
Python简介 Python是一种非常流行的开源编程语言.得益于无尽的模块选项,Python今天广泛用于脚本语言.Web开发.移动和桌面在许多领域.随着人工智能的复兴,数据科学的崛起,Python更 ...
- canvas绘制工作流之绘制节点
上一篇我们介绍了canvas绘制工作流的大概步骤,接下来会有系列文章细致的介绍怎么用canvas绘制工作流:这篇文章主要介绍用canvas绘制流程节点. 绘制前我们需要先准备一张节点图片,例如::好了 ...
- [增强for循环] 格式
比如:
- 新手如何正确安装python,视图详解
今天教新手如何安装python,因为Python是跨平台的,它可以运行在Windows.Mac和各种Linux/Unix系统上.在Windows上写Python程序,放到Linux上也是能够运行的.学 ...
- Verilog模块概念和实例化#转载自Jason from Lofter
Verilog模块概念和实例化 模块的概念 模块(module)是verilog最基本的概念,是v设计中的基本单元,每个v设计的系统中都由若干module组成. 1.模块在语言形式上是以关键词modu ...
- Serlvet之cookie和session学习
HTTP 协议 Web通信需要一种语言,就像中国人讲中文,欧美说英文,Web使用的HTTP协议,也叫超文本协议. 使用HTTP协议的人分为两类:客户端和服务端.请求资源的角色是客户端,提供资源的是服务 ...