Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to integrate WebSocket in Netty

2025-03-31 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/02 Report--

Netty how to integrate WebSocket, many novices are not very clear about this, in order to help you solve this problem, the following editor will explain for you in detail, people with this need can come to learn, I hope you can gain something.

The WebSocket protocol is based on

A new network protocol of TCP. It implements full-duplex (full-duplex) communication between the browser and the server-- allowing the server to actively send information to the client. It first makes a Http connection, and then converts it to a TCP connection.

Now let's do a WebSocket HelloWorld, which means to receive a message sent by a WebSocket client, and then swipe it to all connected clients, and everyone can see this message.

@ Slf4j@AllArgsConstructorpublic class WebSocketServer {private int port; public void run () throws InterruptedException {EventLoopGroup boss = new NioEventLoopGroup (); EventLoopGroup worker = new NioEventLoopGroup (); try {ServerBootstrap bootstrap = new ServerBootstrap () Bootstrap.group (boss,worker) .channel (NioServerSocketChannel.class) .option (ChannelOption.SO_BACKLOG,1024) .childOption (ChannelOption.TCP_NODELAY) True) .childHandler (new ChannelInitializer () {@ Override protected void initChannel (SocketChannel ch) throws Exception {/ / web decoder based on http protocol ch.pipeline () .childHandler (new HttpServerCodec ()) / / support for a pair of large data streams ch.pipeline () .addLast (new ChunkedWriteHandler ()); / / A pair of http message are aggregated into FullHttpRequest or FullHttpResponse ch.pipeline () .addLast (new HttpObjectAggregator (1024 * 64)) / / the websocket server handles the protocol The path assigned to the client connection access / / the handler will help you deal with some heavy and complicated things / / will help you handle the handshake: handshaking (close,ping,pong) ping + pong = heartbeat / / for websocket, it is all transmitted in frames Different data types correspond to different frames (). AddLast (new WebSocketServerProtocolHandler ("/ ws")) / / add our custom channel processor ch.pipeline () .addLast (new WebSocketHandler ());}}); log.info ("starting server"); ChannelFuture future = bootstrap.bind (port) .sync () Future.channel (). CloseFuture (). Sync ();} finally {worker.shutdownGracefully (); boss.shutdownGracefully ();}

Channel processor

/ * TextWebSocketFrame: in netty, an object used to process text specifically for websocket. Frame is the carrier of messages * / @ Slf4jpublic class WebSocketHandler extends SimpleChannelInboundHandler {/ / channel private static ChannelGroup clients = new DefaultChannelGroup (GlobalEventExecutor.INSTANCE) used to record and manage all clients; @ Override protected void channelRead0 (ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {/ / get the messages transmitted by the client String content = msg.text () Log.info ("data received" + content); clients.stream () .forEach (channel-> channel.writeAndFlush (new TextWebSocketFrame ("[server in]" + LocalDateTime.now () + "received message:" + content) / / the following method is the same as above / / clients.writeAndFlush (new TextWebSocketFrame ("[server in]" + LocalDateTime.now () + / "received message:" + content)) } / * when the client connects to the server (opens the connection) * gets the client's channel and puts it into ChannelGroup for management * @ param ctx * @ throws Exception * / @ Override public void handlerAdded (ChannelHandlerContext ctx) throws Exception {clients.add (ctx.channel ()) } @ Override public void handlerRemoved (ChannelHandlerContext ctx) throws Exception {/ / when handlerRemoved,ChannelGroup is triggered, the corresponding client's channel / / is automatically removed, so the following statement does not write / / clients.remove (ctx.channel ()); log.info ("client is disconnected, channel corresponds to a long id:" + ctx.channel (). Id (). AsLongText () Log.info ("the client is disconnected and the short id for channel is:" + ctx.channel () .id () .asShortText ());}}

Server startup

@ SpringBootApplicationpublic class WebsocketApplication {public static void main (String [] args) throws InterruptedException {SpringApplication.run (WebsocketApplication.class, args); new WebSocketServer (10101) .run ();}}

The client writes a html file with the following code

Send message: accept message: window.CHAT = {socket: null Init: function () {if (window.WebSocket) {CHAT.socket = new WebSocket ("ws://127.0.0.1:9999/ws") CHAT.socket.onopen = function () {console.log ("connection established successfully") CHAT.chat (1Jol nullrec nullrep app.CONNECT Jol null) / / get the unread message fetchUnReadMsg () each time you connect / / send heartbeat regularly, setInterval every 30 seconds ("CHAT.keepalive ()", 30000) }, CHAT.socket.onclose = function () {console.log ("connection closed") }, CHAT.socket.onerror = function () {console.log ("error occurred") }, CHAT.socket.onmessage = function (e) {console.log ("received message" + e.data) Var receiveMsg = document.getElementById ("receiveMsg"); var html = receiveMsg [XSS _ clean]; var chatMsg = JSON.parse (e.data) ReceiveMsg [XSS _ clean] = html + "" + chatMsg.msg; / / message signing CHAT.chat (chatMsg.receiverId,null,null,app.SIGNED,String (chatMsg.msgId)) }} else {alert ("browsers do not support WebSocket protocol...") }}, chat: function (senderId,receiverId,msg,action,extand) {var chatMsg = new app.ChatMsg (senderId,receiverId,msg,null) Var dataContent = new app.DataContent (action,chatMsg,extand); CHAT.socket.send (JSON.stringify (dataContent)) }, keepalive: function () {CHAT.chat (1 CHAT.chat nullpencil nullpencil app. KEEPALIVE pageNull); fetchUnReadMsg () }} CHAT.init () Function fetchUnReadMsg () {mui.ajax ('http://127.0.0.1:8008/notification-anon/getunreadmeg?receiverid=1',{ data: {}, dataType:'json') / / the server returns data in json format type:'post',//HTTP request type timeout:10000,// timeout is set to 10 seconds Success:function (data) {if (data.code = = 200) {var contactList = data.data; var ids = "" Console.log (JSON.stringify (contactList)); var receiveMsg = document.getElementById ("receiveMsg"); for (var I = 0 Tinci)

< contactList.length;i++) { var msgObj = contactList[i]; var html = receiveMsg[xss_clean]; receiveMsg[xss_clean] = html + "" + msgObj.msg; ids = ids + msgObj.msgId + ","; } //批量签收未读消息 CHAT.chat(1,null,null,app.SIGNED,ids); } } }); } 用户id为2的代码,文件名receive.html 发送消息: 接受消息: window.CHAT = { socket: null, init: function() { if (window.WebSocket) { CHAT.socket = new WebSocket("ws://127.0.0.1:9999/ws"); CHAT.socket.onopen = function() { console.log("连接建立成功"); CHAT.chat(1,null,null,app.CONNECT,null); //每次连接的时候获取未读消息 fetchUnReadMsg(); //定时发送心跳,30秒一次 setInterval("CHAT.keepalive()",30000); }, 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[xss_clean]; var chatMsg = JSON.parse(e.data); receiveMsg[xss_clean] = html + "" + chatMsg.msg; //消息签收 CHAT.chat(chatMsg.receiverId,null,null,app.SIGNED,String(chatMsg.msgId)); } }else { alert("浏览器不支持WebSocket协议..."); } }, chat: function(senderId,receiverId,msg,action,extand) { var chatMsg = new app.ChatMsg(senderId,receiverId,msg,null); var dataContent = new app.DataContent(action,chatMsg,extand); CHAT.socket.send(JSON.stringify(dataContent)); }, keepalive: function() { CHAT.chat(1,null,null,app.KEEPALIVE,null); fetchUnReadMsg(); } } CHAT.init(); function fetchUnReadMsg() { mui.ajax('http://127.0.0.1:8008/notification-anon/getunreadmeg?receiverid=2',{ data:{}, dataType:'json',//服务器返回json格式数据 type:'post',//HTTP请求类型 timeout:10000,//超时时间设置为10秒; success:function(data){ if (data.code == 200) { var contactList = data.data; var ids = ""; console.log(JSON.stringify(contactList)); var receiveMsg = document.getElementById("receiveMsg"); for (var i = 0;i < contactList.length;i++) { var msgObj = contactList[i]; var html = receiveMsg[xss_clean]; receiveMsg[xss_clean] = html + "" + msgObj.msg; ids = ids + msgObj.msgId + ","; } //批量签收未读消息 CHAT.chat(2,null,null,app.SIGNED,ids); } } }); } $(function () { $("#button").click(function () { var form = new FormData(); form.append("file", document.getElementById("file").files[0]); $.ajax({ url: "http://xxx.xxx.xxx.xxx:8010/files-anon/fdfsupload", //后台url data: form, cache: false, async: false, type: "POST", //类型,POST或者GET dataType: 'json', //数据返回类型,可以是xml、json等 processData: false, contentType: false, success: function (data) { //成功,回调函数 if (data.code == 200) { console.log(data.data); CHAT.chat(1,2,"

", app.CHAT,null);}}) })})

It means to use ajax to access our uploaded file Controller, get the url after the upload is successful, and then splice the url into

When called ordinary chat messages can be sent out.

The front-end code with user id 2 is the same.

Send a message:

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report