Spring WebSocket and Socketjs realize single chat group chat, broadcast message push details

Source: Internet
Author: User
Tags sendmsg tojson

Spring WebSocket and Socketjs realize single chat group chat, broadcast message push details WebSocket Brief introduction

With the development of the Internet, the traditional HTTP protocol has been difficult to meet the increasingly complex needs of web applications. In recent years, with the birth of HTML5, the WebSocket protocol has been proposed, it realizes full duplex communication between browser and server, expands the communication function between browser and service, and enables the server to send data to the client actively.

We know that the traditional HTTP protocol is stateless, each request must be initiated by the client (such as a browser), the server to return response results after processing, and the service side is very difficult to actively send data to the client, the client is the active side, The traditional Web mode with the passive side of the server is less troublesome for Web applications where information is not changing frequently, but it is inconvenient for Web applications involving real-time information, such as applications with instant messaging, real-time data, and subscription push. Before the WebSocket specification was introduced, developers would often use a compromise solution: Polling (polling) and Comet technology to achieve these real-time features. In fact, the latter is also a kind of polling, but some improvement.

   Polling is the most primitive solution for implementing real-time Web applications. Polling technology requires clients to periodically send requests to the server at set intervals, frequently querying for new data changes. Obviously, this approach leads to excessive unnecessary requests, wasteful traffic, and server resources.

  Comet Technology can also be divided into long polling and streaming technology . Long Polling improves the polling technology mentioned above, reducing useless requests. It sets the expiration time for some data and sends the request to the server when the data expires, a mechanism suitable for data changes that are not particularly frequent. Streaming technology usually refers to the client using a hidden window and the server to establish an HTTP long connection, the server will constantly update the connection state to keep the HTTP long connection to survive, so that the server can use this long connection to actively send data to the client; streaming technology in a large concurrency environment, May test performance on the server side.

Both of these technologies are based on the request-response model, which is not really real-time technology; Each request and response wastes a certain amount of traffic on the same header information, and the complexity of the development is greater.

With the launch of the HTML5 WebSocket, the real real-time communication of the web, so that b/s model with the C/s mode of real-time communication capabilities. WebSocket Workflow is this: the browser through JavaScript to the server to establish a WebSocket connection request, after the WebSocket connection is established successfully, the client and the server can transfer data over a TCP connection. Because the WebSocket connection is essentially a TCP connection and does not require duplicate header data per transmission, it has a much smaller data transfer than polling and comet technology. This article does not introduce the WebSocket specification in detail, mainly introduces the implementation of the next websocket in the Java Web.

Java EE 7 shows the Jsr-356:java API for WebSocket specification. Many web containers, such as Tomcat,nginx,jetty, support WebSocket. Tomcat starts with support for WebSocket from 7.0.27, supports JSR-356 from 7.0.47, and the following demo code needs to be deployed in versions above Tomcat7.0.47 to run.

Project Structure diagram:

Related code:

Pom.xml:

<?xml version= "1.0" encoding= "UTF-8"? ><project xmlns= "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http ://www.w3.org/2001/XMLSchema-instance "xsi:schemalocation=" http://maven.apache.org/POM/4.0.0/http Maven.apache.org/xsd/maven-4.0.0.xsd "> <modelVersion>4.0.0</modelVersion> <groupid>com</ Groupid> <artifactId>websocket-singlechat</artifactId> <version>1.0-snapshot</version > <packaging>war</packaging> <name>websocket-singlechat Maven webapp</name> <!--fixme Change it to the project ' s website-<url>http://www.example.com</url> <properties> &LT;PROJEC T.build.sourceencoding>utf-8</project.build.sourceencoding> <maven.compiler.source>1.7</ Maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> < dependencies> <dependency> <groupId>junit</groupId> <arTifactid>junit</artifactid> <version>4.11</version> <scope>test</scope> < /dependency> <dependency> <groupId>javax</groupId> <artifactid>javaee-api</arti factid> <version>7.0</version> </dependency> <dependency> <groupid>com.go Ogle.code.gson</groupid> <artifactId>gson</artifactId> <version>2.7</version> & lt;/dependency> </dependencies> <build> <finalName>websocket-singlechat</finalName> &lt      ;p luginmanagement><!--Lock plugins versions to avoid using Maven defaults (could be moved to parent POM)- <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <v Ersion>3.0.0</version> </plugin> <!--see http://maven.apache.org/ref/current/maven-core/d Efault-bindings.html#pluGin_bindings_for_war_packaging-<plugin> <artifactid>maven-resources-plugin</artifact id> <version>3.0.2</version> </plugin> <plugin> <artifactid& gt;maven-compiler-plugin</artifactid> <version>3.7.0</version> </plugin> &L T;plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.20.1</versio          n> </plugin> <plugin> <artifactId>maven-war-plugin</artifactId> <version>3.2.0</version> </plugin> <plugin> <artifactid>maven-instal          l-plugin</artifactid> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </p Lugin> </plugIns> </pluginManagement> </build></project> 

Chatsocket:

Package Com.home.chat;import Java.io.ioexception;import Java.util.arraylist;import java.util.date;import Java.util.hashmap;import java.util.hashset;import java.util.list;import Java.util.map;import java.util.Set;import Javax.websocket.onclose;import Javax.websocket.onmessage;import Javax.websocket.onopen;import Javax.websocket.session;import Javax.websocket.server.serverendpoint;import Com.google.gson.gson;import Com.home.vo.contentvo;import com.home.vo.message;/** * * */@ServerEndpoint ("/chatsocket") public class Chatsocket {///define a global variables collection sockets, the user holds the communication pipeline for each logged-on user private static set<chatsocket> sockets=new Hashset<chat    Socket> ();    Defines a global variable session that holds the user name of the logged-on user private session session; Define a global variable Map,key is the user name, the user corresponding Session is value private static map<string, session> map=new hashmap<string, Sessi    On> ();    Defines an array to hold all logged-in users, which are displayed in the user list bar of the chat page, private static list<string>names=new arraylist<string> (); Private String username;    Private Gson gson=new Gson (); /* * Monitor User Login */@OnOpen public void Open (session session) {SYSTEM.OUT.PRINTLN ("set up a socket channel" + Sessio        N.getid ());        This.session = session;        Save the user session information on the current connection to Scokets in Sockets.add (this);        Get all the parameter information behind the URL path String queryString = session.getquerystring ();        System.out.println ();        Intercept = Subsequent parameter information (user name), assigning parameter information to global user name This.username = querystring.substring (querystring.indexof ("=") +1);        Each login to a user, the user name is stored in the names array, to refresh the Friend list Names.add (this.username);        Deposit the current logged-in user and the corresponding session to map This.map.put (This.username, this.session);        System.out.println ("User" +this.username+ "Enter chat room");        Message message = new Message ();        Message.setalert ("User" +this.username+ "Enter chat room");        Deposit all currently logged-in users into a message for broadcast to the chat page message.setnames (names);    Broadcast the chat information to all communication pipelines (sockets) broadcast (sockets, Gson.tojson (message)); }/* Log out of login */@OnClose public void Close (Session session) {//Remove the Communication pipe sockets.remove (this) from the logged-in user;        Remove the user name from names to refresh the buddy list names.remove (this.username);        Message message = new Message ();        System.out.println ("User" +this.username+ "Exit chat room"); Message.setalert (this.username+ "exit the current chat room!!!        ");        Refresh Friends List message.setnames (names);    Broadcast (sockets, Gson.tojson (message)); }/* Receives the message sent by the client and then determines whether it is a broadcast or a single chat */@OnMessage public void receive (Session session,string msg) throws IOE        xception{//Turn client messages into JSON objects Contentvo VO = Gson.fromjson (msg, contentvo.class);            If it's a group chat, it's like a message broadcast to everyone if (Vo.gettype () ==1) {Message message = new Message ();            Message.setdate (New Date (). toLocaleString ());            Message.setfrom (This.username);            Message.setsendmsg (Vo.getmsg ());        Broadcast (sockets, Gson.tojson (message));            }else{Message message = new Message (); Message.setdAte (new Date (). toLocaleString ());            Message.setfrom (This.username);            Message.setalert (Vo.getmsg ());            Message.setsendmsg ("<font color=red> is secretly talking about you:</font>" +vo.getmsg ());            String to = Vo.getto ();            Get the session session To_session = This.map.get (to) for the single-chat object according to the name of the single-chat object;        If it is a single chat, send the message to the other party To_session.getbasicremote (). SendText (Gson.tojson (message)); }/* * Broadcast message */public void Broadcast (Set<chatsocket>sockets, String msg) {//traverse all current connection pipes, will pass Information sent to each pipeline for (Chatsocket socket:sockets) {try {//Send message via session socket            . Session.getbasicremote (). SendText (msg);            } catch (IOException e) {e.printstacktrace (); }        }    }}

Serverconfig:

package com.home.config;import java.util.Set;import javax.websocket.Endpoint;import javax.websocket.server.ServerApplicationConfig;import javax.websocket.server.ServerEndpointConfig;/** * 项目启动时会自动启动,类似与ContextListener. * 是webSocket的核心配置类。 * */public class ServerConfig implements ServerApplicationConfig {    //扫描src下所有类@ServerEndPoint注解的类。    @Override    public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scan) {        System.out.println("扫描到"+scan.size()+"个服务端程序");        return scan;    }    //获取所有以接口方式配置的webSocket类。    @Override    public Set<ServerEndpointConfig> getEndpointConfigs(            Set<Class<? extends Endpoint>> point) {        System.out.println("实现EndPoint接口的类数量:"+point.size());        return null;    }}

Loginservlet:

package com.home.servlet;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;public class LoginServlet extends HttpServlet {    public void doGet(HttpServletRequest request,                      HttpServletResponse response)throws IOException,ServletException {    }    public void doPost(HttpServletRequest request,                       HttpServletResponse response)throws IOException,ServletException{        String username = request.getParameter("username");        System.out.println("doPost当前登录用户为"+username);        request.getSession().setAttribute("username",username);        //这里只是简单地模拟登录,登陆之后直接跳转到聊天页面        response.sendRedirect("chat.jsp");    }}

Contentvo:

package com.home.vo;/** * 客户端发送给服务端消息实体 * */public class ContentVo {    private String to;    private String msg;    private Integer type;    public String getTo() {        return to;    }    public void setTo(String to) {        this.to = to;    }    public String getMsg() {        return msg;    }    public void setMsg(String msg) {        this.msg = msg;    }    public Integer getType() {        return type;    }    public void setType(Integer type) {        this.type = type;    }}

Message:

 Package Com.home.vo;import java.util.date;import java.util.list;/** * Server sent to client message entity * */public class Message {PR Ivate String Alert; private list<string> names; Private String sendmsg; Private String from; Private String date; Public String GetDate () {return date; public void SetDate (String date) {this.date = date; } public String getsendmsg () {return sendmsg; } public void Setsendmsg (String sendmsg) {this.sendmsg = sendmsg; } public String Getfrom () {return from; The public void Setfrom (String from) {this.from = from; } public String Getalert () {return alert; The public void Setalert (String alert) {This.alert = alert; } public list<string> GetNames () {return names; } public void Setnames (list<string> names) {this.names = names; } public Message () {super (); }}

Xml:

<?xml version="1.0" encoding="UTF-8"?><web-app version="2.5"         xmlns="http://java.sun.com/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">  <display-name>Archetype Created Web Application</display-name>  <servlet>    <description></description>    <display-name>LoginServlet</display-name>    <servlet-name>LoginServlet</servlet-name>    <servlet-class>com.home.servlet.LoginServlet</servlet-class>  </servlet>  <servlet-mapping>    <servlet-name>LoginServlet</servlet-name>    <url-pattern>/LoginServlet</url-pattern>  </servlet-mapping>  <welcome-file-list>    <welcome-file>index.jsp</welcome-file>  </welcome-file-list></web-app>

Chat.jsp:

<%@ page language= "java" contenttype= "text/html; Charset=utf-8 "pageencoding=" Utf-8 "%><! DOCTYPE HTML PUBLIC "-//w3c//dtd HTML 4.01 transitional//en" "Http://www.w3.org/TR/html4/loose.dtd" >

LOGIN.JSP:

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
Project Demo:

Spring WebSocket and Socketjs realize single chat group chat, broadcast message push details

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.