In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly shows you "how to use Springboot+netty to achieve Web chat room", the content is easy to understand, clear, hope to help you solve your doubts, the following let the editor lead you to study and learn "how to use Springboot+netty to achieve Web chat room" this article.
I. the creation of the project
Create a new Spring project:
Select the JDK version:
Select Spring Web:
Settings for project name and location:
II. Code writing
Import the .jar package:
Gson: https://search.maven.org/artifact/com.google.code.gson/gson/2.8.9/jar
DemoApplication:
Package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.ConfigurableApplicationContext;import org.springframework.core.env.Environment;import java.net.InetAddress;import java.net.UnknownHostException;@SpringBootApplicationpublic class DemoApplication {public static void main (String [] args) throws UnknownHostException {ConfigurableApplicationContext application = SpringApplication.run (DemoApplication.class, args); Environment env = application.getEnvironment (); String host = InetAddress.getLocalHost (). GetHostAddress () String port = env.getProperty ("server.port"); System.out.println ("[- -]"); System.out.println ("chat room started successfully! Click to enter:\ t http://" + host + ":" + port); System.out.println ("[- -"); WebSocketServer.inst () .run (53134);}}
User:
Package com.example.demo;import java.util.Objects;public class User {public String id; public String nickname; public User (String id, String nickname) {super (); this.id = id; this.nickname = nickname;} public String getId () {return id;} public void setId (String id) {this.id = id } public String getNickname () {return nickname;} public void setNickname (String nickname) {this.nickname = nickname;} @ Override public boolean equals (Object o) {if (this = = o) return true; if (o = = null | | getClass ()! = o.getClass ()) return false; User user = (User) o Return id.equals (user.getId ());} @ Override public int hashCode () {return Objects.hash (id);} public String getUid () {return id;}}
SessionGroup:
Package com.example.demo;import com.google.gson.Gson;import io.netty.channel.ChannelFuture;import io.netty.channel.ChannelFutureListener;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.group.ChannelGroup;import io.netty.channel.group.ChannelGroupFuture;import io.netty.channel.group.DefaultChannelGroup;import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;import io.netty.util.concurrent.ImmediateEventExecutor;import org.springframework.util.StringUtils;import java.util.Iterator;import java.util.Map Import java.util.concurrent.ConcurrentHashMap;public final class SessionGroup {private static SessionGroup singleInstance = new SessionGroup (); / / group mapping private ConcurrentHashMap groupMap = new ConcurrentHashMap (); public static SessionGroup inst () {return singleInstance;} public void shutdownGracefully () {Iterator groupIterator = groupMap.values () .iterator (); while (groupIterator.hasNext ()) {ChannelGroup group = groupIterator.next () Group.close ();}} public void sendToOthers (Map result, SocketSession s) {/ / get group ChannelGroup group = groupMap.get (s.getGroup ()); if (null = = group) {return;} Gson gson=new Gson (); String json = gson.toJson (result) / / messages sent by yourself are not returned to themselves / / Channel channel = s.getChannel (); / / remove channels from the group / / group.remove (channel); ChannelGroupFuture future = group.writeAndFlush (new TextWebSocketFrame (json)); future.addListener (f-> {System.out.println ("finish sending:" + json); / / group.add (channel)) / / add again after sending the message. });} public void addSession (SocketSession session) {String groupName = session.getGroup (); if (StringUtils.isEmpty (groupName)) {/ / empty, return return;} ChannelGroup group = groupMap.get (groupName) directly; if (null = = group) {group = new DefaultChannelGroup (ImmediateEventExecutor.INSTANCE); groupMap.put (groupName, group) } group.add (session.getChannel ());} / * close the connection and send a notification message * / public void closeSession (SocketSession session, String echo) {ChannelFuture sendFuture = session.getChannel () .writeAndFlush (new TextWebSocketFrame (echo)) before closing SendFuture.addListener (new ChannelFutureListener () {public void operationComplete (ChannelFuture future) {System.out.println ("close connection:" + echo); future.channel () .close ();}}) } / * close connection * / public void closeSession (SocketSession session) {ChannelFuture sendFuture = session.getChannel () .close (); sendFuture.addListener (new ChannelFutureListener () {public void operationComplete (ChannelFuture future) {System.out.println ("send all done:" + session.getUser () .getNickname ());}})) } / * send message * @ param ctx context * @ param msg message to be sent * / public void sendMsg (ChannelHandlerContext ctx, String msg) {ChannelFuture sendFuture = ctx.writeAndFlush (new TextWebSocketFrame (msg)); sendFuture.addListener (f-> {/ / send listening System.out.println ("complete for all send:" + msg);}) }}
SocketSession:
Package com.example.demo;import io.netty.channel.Channel;import io.netty.channel.ChannelHandlerContext;import io.netty.util.AttributeKey;import java.util.HashMap;import java.util.Map;import java.util.UUID;public class SocketSession {public static final AttributeKey SESSION_KEY = AttributeKey.valueOf ("SESSION_KEY"); / * user implements the core of server session management * / channel private Channel channel / / user private User user; / / session uniquely marks the session variable attribute value * / private Map map = new HashMap () stored in private final String sessionId; private String group; / * session; public SocketSession (Channel channel) {/ / Note the parameter channel. Different clients will have different channel this.channel = channel; this.sessionId = buildNewSessionId (); channel.attr (SocketSession.SESSION_KEY) .set (this);} / reverse navigation public static SocketSession getSession (ChannelHandlerContext ctx) {/ / pay attention to ctx, different clients will have different ctx Channel channel = ctx.channel (); return channel.attr (SocketSession.SESSION_KEY). Get () Public static SocketSession getSession (Channel channel) {return channel.attr (SocketSession.SESSION_KEY). Get ();} public String getId () {return sessionId;} private static String buildNewSessionId () {String uuid = UUID.randomUUID () .toString (); return uuid.replaceAll ("-", ") } public synchronized void set (String key, Object value) {map.put (key, value);} public synchronized T get (String key) {return (T) map.get (key);} public boolean isValid () {return getUser ()! = null? True: false;} public User getUser () {return user;} public void setUser (User user) {this.user = user;} public String getGroup () {return group;} public void setGroup (String group) {this.group = group;} public Channel getChannel () {return channel;}}
WebSocketServer:
Package com.example.demo;import io.netty.bootstrap.ServerBootstrap;import io.netty.channel.Channel;import io.netty.channel.ChannelInitializer;import io.netty.channel.ChannelPipeline;import io.netty.channel.EventLoopGroup;import io.netty.channel.nio.NioEventLoopGroup;import io.netty.channel.socket.SocketChannel;import io.netty.channel.socket.nio.NioServerSocketChannel;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.codec.http.websocketx.extensions.compression.WebSocketServerCompressionHandler;import io.netty.handler.stream.ChunkedWriteHandler;import io.netty.handler.timeout.IdleStateHandler;import java.util.concurrent.TimeUnit;public class WebSocketServer {private static WebSocketServer wbss; private static final int READ_IDLE_TIME_OUT = 60; / / read timeout private static final int WRITE_IDLE_TIME_OUT = 0 governance / write timeout private static final int ALL_IDLE_TIME_OUT = 0 / / all timeout public static WebSocketServer inst () {return wbss = new WebSocketServer ();} public void run (int port) {EventLoopGroup bossGroup = new NioEventLoopGroup (); EventLoopGroup workerGroup = new NioEventLoopGroup (); ServerBootstrap b = new ServerBootstrap () B.group (bossGroup, workerGroup) .channel (NioServerSocketChannel.class) .childHandler (new ChannelInitializer () {@ Override protected void initChannel (SocketChannel ch) throws Exception {ChannelPipeline pipeline = ch.pipeline () / / Netty's own http decoder and encoder, message-level HTTP request decoding and encoding pipeline.addLast (new HttpServerCodec ()) / / ChunkedWriteHandler is used for big data's partition transfer / / is mainly used to deal with large data streams, such as a 1G file that will definitely burst jvm memory if you transfer it directly; / / after the addition, you don't have to worry about pipeline.addLast (new ChunkedWriteHandler ()). / / HttpObjectAggregator is used to completely parse Http message body requests / / to convert multiple messages into a single full FullHttpRequest or FullHttpResponse / / the reason is that the HTTP decoder generates multiple message objects HttpRequest/HttpResponse,HttpContent,LastHttpContent pipeline.addLast (new HttpObjectAggregator (64 * 1024)) in each HTTP message. / / WebSocket data compression pipeline.addLast (new WebSocketServerCompressionHandler ()); / / WebSocketServerProtocolHandler is the listening address for configuring websocket / protocol packet length limit pipeline.addLast (new WebSocketServerProtocolHandler ("/ ws", null, true, 10 * 1024)) / / when the connection does not receive a message within 60 seconds, an IdleStateEvent event will be triggered / / this event is handled to pipeline.addLast (new IdleStateHandler (READ_IDLE_TIME_OUT, WRITE_IDLE_TIME_OUT, ALL_IDLE_TIME_OUT, TimeUnit.SECONDS) by HeartbeatHandler's userEventTriggered method) / / WebSocketServerHandler, TextWebSocketFrameHandler are custom logic processors, pipeline.addLast (new WebSocketTextHandler ());}}); Channel ch = b.bind (port). SyncUninterruptibly (). Channel (); ch.closeFuture (). SyncUninterruptibly () / / returns the runtime object Runtime.getRuntime () .addShutdownHook associated with the current Java application (new Thread () {@ Override public void run () {SessionGroup.inst () .shutdownGracefully (); bossGroup.shutdownGracefully (); workerGroup.shutdownGracefully ();}});}}
WebSocketTextHandler:
Package com.example.demo;import com.google.gson.Gson;import com.google.gson.reflect.TypeToken;import io.netty.channel.ChannelHandlerContext;import io.netty.channel.SimpleChannelInboundHandler;import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;import io.netty.handler.timeout.IdleState;import io.netty.handler.timeout.IdleStateEvent;import java.util.HashMap;import java.util.Map Public class WebSocketTextHandler extends SimpleChannelInboundHandler {/ / @ Override protected void channelRead (ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {SocketSession session = SocketSession.getSession (ctx); TypeToken typeToken = new TypeToken () {}; Gson gson=new Gson (); java.util.Map map = gson.fromJson (msg.text (), typeToken.getType ()); User user = null Switch (map.get ("type")) {case "msg": Map result = new HashMap (); user = session.getUser (); result.put ("type", "msg"); result.put ("msg", map.get ("msg")); result.put ("sendUser", user.getNickname ()) SessionGroup.inst () .sendToOthers (result, session); break; case "init": String room = map.get ("room"); session.setGroup (room); String nick = map.get ("nick"); user = new User (session.getId (), nick) Session.setUser (user); SessionGroup.inst (). AddSession (session); break } @ Override public void userEventTriggered (ChannelHandlerContext ctx, Object evt) throws Exception {/ / whether the handshake is successful, upgrade to Websocket protocol if (evt = = WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {/ / handshake is successful, remove HttpRequestHandler, so you will not receive any message / / and add the Channel with successful handshake to ChannelGroup new SocketSession (ctx.channel ()) } else if (evt instanceof IdleStateEvent) {IdleStateEvent stateEvent = (IdleStateEvent) evt; if (stateEvent.state () = = IdleState.READER_IDLE) {System.out.println ("bb22");}} else {super.userEventTriggered (ctx, evt);}} @ Override protected void messageReceived (ChannelHandlerContext channelHandlerContext, TextWebSocketFrame textWebSocketFrame) throws Exception {}
Then create a test.html outside the project:
Group chat room body {margin-right:50px; margin-left:50px;} .ddois {position: fixed; left: 120px; bottom: 30px;} group name: nickname: send var webSocket If (window.WebSocket) {webSocket = new WebSocket ("ws://localhost:53134/ws");} else {alert ("Sorry, your browser does not support WebSocket protocol!");} / / callback event webSocket.onopen = function () {console.log ("websocket has been connected") / / setMessageInnerHTML ("websocket has been connected");}; / / callback method webSocket.onerror = function (event) {console.log ("error"); / / setMessageInnerHTML ("connection failure");} / / callback method webSocket.onclose = function () {console.log ("connection closed...");} / / callback method webSocket.onmessage = function (event) {console.log ("bbdds") that received the message Var data = JSON.parse (event.data) var msg = data.msg; var nick = data.sendUser; switch (data.type) {case 'init': console.log ("mmll"); break; case' msg': console.log ("bblld") SetMessageInnerHTML (nick+ ":" + msg); break; default: break;}} function enter () {var map = new Map (); var nick=document.getElementById ('nick'). Value; var room=document.getElementById (' room'). Value Map.set ("type", "init"); map.set ("nick", nick); console.log (room); map.set ("room", room); var message = Map2Json (map); webSocket.send (message) } function send () {var msg = document.getElementById ('text'). Value; var nick = document.getElementById (' nick'). Value; console.log ("1:" + msg); if (msg! = null & & msg! = ") {var map = new Map () Map.set ("type", "msg"); map.set ("msg", msg); var map2json=Map2Json (map); if (map2json.length < 8000) {console.log ("4:" + map2json); webSocket.send (map2json) } else {console.log ("the text is too long, please write less");} / / display the message on the web page function setMessageInnerHTML (innerHTML) {document.getElementById ("message") [xss_clean] + = innerHTML + "" } function Map2Json (map) {var str = "{"; map.forEach (function (value, key) {str + ='"'+ key+'"'+':'+'"'+ value+'",';}) str = str.substring (0pr str.principthmur1) str + = "}"; return str }
Run the project first, then run html
Third, the running effect
The above is all the contents of the article "how to use Springboot+netty to implement Web chat rooms". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!
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.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.