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 缺点:不可靠:发送数据,无需 ...
随机推荐
- 使用Typescript重构axios(十八)——请求取消功能:总体思路
0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...
- 基于cookie的用户登录状态管理
cookie是什么 先来花5分钟看完这篇文章:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies 看完上文,相信大家对cookie已经有 ...
- python—mariadb自动部署主从
import configparser import os def config_mariadb_yum(): exists = os.path.exists('/etc/yum.repos.d/ma ...
- 篇六:项目使用Dubbo
导语:Dubbo是阿里巴巴的一个分布式服务的开源框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA服务化治理方案的核心框架,每天为2,000+个服务提供3,000,000,000 ...
- iOS地理反地理编码--CoreLocation
.sidebar{float:left;width:220px;} .container-fluid>.content{margin-left:240px;} a{color:#0069d6;t ...
- Python 命令行之旅:深入 click 之选项篇
作者:HelloGitHub-Prodesire HelloGitHub 的<讲解开源项目>系列,项目地址:https://github.com/HelloGitHub-Team/Arti ...
- 你能说说Java中Comparable和Comparator的区别吗
之前面试中被问到这个问题,当时不屑(会)回答,下来特意查了查,整理如下. Java 中为我们提供了两种比较机制:Comparable 和 Comparator,二者都是用来实现对象的比较.排序. 下面 ...
- 星际争霸2 AI开发(持续更新)
准备 我的环境是python3.6,sc2包0.11.1 机器学习包下载链接:pysc2 地图下载链接maps pysc2是DeepMind开发的星际争霸Ⅱ学习环境. 它是封装星际争霸Ⅱ机器学习API ...
- iOS界面流畅技巧之微博 Demo 性能优化技巧
微博 Demo 性能优化技巧 我为了演示 YYKit 的功能,实现了微博和 Twitter 的 Demo,并为它们做了不少性能优化,下面就是优化时用到的一些技巧. 预排版 当获取到 API JSON ...
- Linux\CentOS 安装 vsftpd 服务器
安装 查看电脑是否存在 vsftpd 服务器 rmp -qa|grep vsftpd 如果有就删除,没有就使用yum 安装 vsftpd yum -y install vsftpd 配置 在根目录下创 ...