netty结合websocket使用
首先需要在后台建立netty服务器启动类;
package com.cxy; 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; /***
* @ClassName: WsNetty
* @Description:
* @Auther: cxy
* @Date: 2019/2/5:14:15
* @version : V1.0
*/
public class WsNetty {
public static void main(String[] args) throws InterruptedException {
/* 主从线程组模型
*/
EventLoopGroup mainGroup =new NioEventLoopGroup();
EventLoopGroup subGroup=new NioEventLoopGroup();
try {
//创建核心类
ServerBootstrap serverBootstrap =new ServerBootstrap();
serverBootstrap.group(mainGroup,subGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new WSServerInitialzer());//添加助手类
ChannelFuture channelFuture= serverBootstrap.bind().sync(); channelFuture.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
mainGroup.shutdownGracefully();
subGroup.shutdownGracefully();//优雅的关闭主从线程池
} } }
第二创建初始化类;
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; public class WSServerInitialzer extends ChannelInitializer<SocketChannel> { @Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline(); // websocket 基于http协议,所以要有http编解码器
pipeline.addLast(new HttpServerCodec());
// 对写大数据流的支持
pipeline.addLast(new ChunkedWriteHandler());
// 对httpMessage进行聚合,聚合成FullHttpRequest或FullHttpResponse
// 几乎在netty中的编程,都会使用到此hanler
pipeline.addLast(new HttpObjectAggregator(*)); // ====================== 以上是用于支持http协议 ====================== // ====================== 以下是支持httpWebsocket ====================== /**
* websocket 服务器处理的协议,用于指定给客户端连接访问的路由 : /ws
* 本handler会帮你处理一些繁重的复杂的事
* 会帮你处理握手动作: handshaking(close, ping, pong) ping + pong = 心跳
* 对于websocket来讲,都是以frames进行传输的,不同的数据类型对应的frames也不同
*/
pipeline.addLast(new WebSocketServerProtocolHandler("/ws")); // 自定义的handler
pipeline.addLast(new ChatHandler());
} }
第三步:创建助手类
import java.time.LocalDateTime; import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor; /**
*
* @Description: 处理消息的handler
* TextWebSocketFrame: 在netty中,是用于为websocket专门处理文本的对象,frame是消息的载体
*/
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { // 用于记录和管理所有客户端的channle
private static ChannelGroup clients =
new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); @Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg)
throws Exception {
// 获取客户端传输过来的消息
String content = msg.text();
System.out.println("接受到的数据:" + content); // for (Channel channel: clients) {
// channel.writeAndFlush(
// new TextWebSocketFrame(
// "[服务器在]" + LocalDateTime.now()
// + "接受到消息, 消息为:" + content));
// }
// 下面这个方法,和上面的for循环,一致
clients.writeAndFlush(
new TextWebSocketFrame(
"[服务器在]" + LocalDateTime.now()
+ "接受到消息, 消息为:" + content)); } /**
* 当客户端连接服务端之后(打开连接)
* 获取客户端的channle,并且放到ChannelGroup中去进行管理
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
clients.add(ctx.channel());
} @Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
// 当触发handlerRemoved,ChannelGroup会自动移除对应客户端的channel
// clients.remove(ctx.channel());
System.out.println("客户端断开,channle对应的长id为:"
+ ctx.channel().id().asLongText());
System.out.println("客户端断开,channle对应的短id为:"
+ ctx.channel().id().asShortText());
} }
前端页面:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div>发送消息</div>
<input type="text" id="msgContent" />
<input type="button" value="点我发送" onclick="chat.chat1()" />
<div>接受消息</div>
<div id="receiveMsg" style="background-color: gainsboro;"> </div>
<script type="application/javascript"> window.chat={ socket:null,
init:function(){
if(window.WebSocket){
chat.socket =new WebSocket("ws://127.0.0.1:8088/ws");
chat.socket.onopen =function(){
console.log("连接建立成功");
},
chat.socket.onclose =function(){
console.log("连接关闭"); },
chat.socket.onerror =function(){
console.log("连接出错");
},
chat.socket.onmessage =function(e){
console.log("接受到消息"+e.data);
var receiveMsg =document.getElementById("receiveMsg");
var html =receiveMsg.innerHTML;
receiveMsg.innerHTML=html+"<br/>"+e.data; } }else{
alert("浏览器不支持协议");
} },
chat1:function(){
var msg =document.getElementById("msgContent");
chat.socket.send(msg.value); } };
chat.init();
</script>
</body>
</html>
测试结果:

netty结合websocket使用的更多相关文章
- 【Netty】WebSocket
一.前言 前面学习了codec和ChannelHandler之间的关系,接着学习WebSocket. 二.WebSocket 2.1. WebSocket介绍 WebSocket协议允许客户端和服务器 ...
- Netty对WebSocket的支持(五)
Netty对WebSocket的支持(五) 一.WebSocket简介 在Http1.0和Http1.1协议中,我们要实现服务端主动的发送消息到网页或者APP上,是比较困难的,尤其是现在IM(即时通信 ...
- 使用Netty做WebSocket服务端
使用Netty搭建WebSocket服务器 1.WebSocketServer.java public class WebSocketServer { private final ChannelGro ...
- Netty之WebSocket和四种IO介绍
Netty简介 一.什么是netty? 高性能 事件驱动 异步非堵塞 基于NIO的客户端,服务器端编程框架 稳定性和伸缩性 二.Netty的使用场景 高性能领域 多线程并发领域 异步通信领域 ...
- netty实现websocket发送文本和二进制数据
原文:https://huan1993.iteye.com/blog/2433552 最近在学习netty相关的知识,看到netty可以实现 websoket,因此记录一下在netty中实现webso ...
- Netty 搭建 WebSocket 服务端
一.编码器.解码器 ... ... @Autowired private HttpRequestHandler httpRequestHandler; @Autowired private TextW ...
- netty系列之:使用netty搭建websocket服务器
目录 简介 netty中的websocket websocket的版本 FrameDecoder和FrameEncoder WebSocketServerHandshaker WebSocketFra ...
- netty系列之:使用netty搭建websocket客户端
目录 简介 浏览器客户端 netty对websocket客户端的支持 WebSocketClientHandshaker WebSocketClientCompressionHandler netty ...
- Netty 实现 WebSocket 聊天功能
上一次我们用Netty快速实现了一个 Java 聊天程序(见http://www.waylau.com/netty-chat/).现在,我们要做下修改,加入 WebSocket 的支持,使它可以在浏览 ...
- 基于netty的websocket例子
nettyServer package com.atguigu.netty.websocket; import javax.annotation.PostConstruct; import org.s ...
随机推荐
- 2015.3.12 C#运用正则表达式点滴
Regex reg = new Regex(@"\w{1,}@\w{1,}\.(com)?(net)?"); //匹配(1个或多个)(字母或数字或下滑线)@ (1个或多个)(字母或 ...
- 包学会之浅入浅出Vue.js:开学篇
2016年,乃至接下来整个2017年,如果你要问前端技术框架什么最火,那无疑就是前端三巨头:React.Angular.Vue.没错,什么jQuery,seaJs,gulp等都逐渐脱离了热点.面试的时 ...
- Javascript面向对象(二):构造函数的继承
这个系列的第一部分,主要介绍了如何"封装"数据和方法,以及如何从原型对象生成实例. 今天要介绍的是,对象之间的"继承"的五种方法. 比如,现在有一个" ...
- jdbc.properties 文件的配置
jdbc.properties文件的配置 使用配置文件访问数据库的优点是: 一次编写随时调用,数据库类型发生变化只需要修改配置文件. 配置文件的设置: 在配置文件中,key-value对应的方式编 ...
- web网页 页面布局的几种方式(转)
web网页 页面布局的几种方式 转载 2017年06月16日 12:19:40 2218 网页基本布局方式: (1)流式布局 Fluid 流布局与固定宽度布局基本不同点 就在于对网站尺寸的侧量单位不同 ...
- CF938D Buy a Ticket
这个题都想不出来,感觉
- Servlet处理表单数据
Servlet 表单数据 很多情况下,需要传递一些信息,从浏览器到 Web 服务器,最终到后台程序.浏览器使用两种方法可将这些信息传递到 Web 服务器,分别为 GET 方法和 POST 方法. 使用 ...
- 关于用Date类计算活了多少天和用Calendar类计算闰年的demo
在javaSE阶段,Date类和Calendar类以后会经常用到 这两个类当中的一些常用方法 通过两个demo 进行学习和练习 第一个要求如下:让用户自己输入yyyy-MM-dd 格式的年月日 然后得 ...
- Charles常见问题汇总
Charles是一款很好用的抓包修改工具,但是如果你不是很熟悉这个工具的话,肯定会遇到各种感觉很莫名其妙的状况,这里就来帮你一一解答下面再说说charles的一些其他常用的功能. 选择请求后,右键可以 ...
- [学习笔记]_exit和exit深入理解
#include<stdio.h> #include<stdlib.h> #include<string.h> #include <unistd.h> ...