Le tutoriel suivant est un système CRM de l'entreprise que j'ai participé au développement d'une entreprise et a réglé certaines informations pertinentes. Il existe de nombreuses fonctions de poussée de messages dans le système, et la technologie WebSocket y est utilisée. L'éditeur suivant l'a compilé et partagé sur la plate-forme du réseau Wulin pour votre référence
1. Dépendance Maven
<Dependency> <GroupId> javax.servlet </rom grouped> <Artifactid> javax.servlet-api </ artifactid> <version> 3.1.0 </-version> </dependency> <Dedency> <proupId> com.fasterxml.jackson.core </proupId> <Artifactid> jackson-core </ artifactid> <wrise> 2.3. 0 </ version> </Dependency> <Dedency> <ProupId> com.fasterxml.jackson.core </prôdId> <Artifactid> jackson-core </ Artifactid> <Dersion> 2.3.0 </ version> </Dedency> <Dedency> <ProupId> com.fasterxml.jackson.core </roulid> <ArtifActid> Jackson -Databind </ artifactive> <version> 2.3.0 </ version> </dependency> <dependency> <proupId> org.springframework </proupId> <ErfactId> Spring-websocket </refactive> <version> 4.0.1. Release </ Version> </Dependency> <Dedency> <GroupId> org.springFramework </rolgleId> <ArtifACTID> Spring-Messaging </ ArtifactId> <DERVIÈRE> 4.0.1.release </DERNIERSE> </Dependance>
2. Configuration de la filet
<? xml version = "1.0" Encoding = "UTF-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: context = "http://www.springframework.org/schema/cont ext "xmlns: mvc =" http://www.springframework.org/schema/mvc "xmlns: tx =" http://www.springframework.org/schema/tx " xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: WebSocket = "http://www.springframework.org/schema/websocket" xsi: schemalation = "http: // www .springframework.org / schema / landshttp: //www.springframework.org/schema/beans/spring-beans-3.1.xsdhttp: //www.springframework.org/schema/context/spring -context-3.1.xsdhttp: //www.springframework.org/schema/mvchttp: //www.springframework.o RG / Schema / MVC / Spring-MVC-3.1.xsdhttp: //www.springframework.org/schema/txhttp: //www.spr ingframework.org/schema/tx/spring-tx-3.1.xsdhttp://www.springframework.org/schema/websocketthttp://www.springframework.org/schema/websocket/spring-websocket.xsd">.... id = "WebSocket" /> <WebSocket: Handlers> <hese WebSocket: mapping path = "/ WebSocket" handler = "WebSocket" /> <hebsocket: handshake-interceptors> <ean /> <hebsocket: handshake-interceptors> </ Websocket: Handlers> </ Beans>
Parmi eux, le chemin correspondant au chemin est le chemin d'interface qui a été réglé via le protocole WS dans la section précédente.
3. Implémentation de la poignée de main Interceptor
package cn.bridgeli.websocket; import cn.bridgeli.utils.userManager; import Cn.bridgeli.util.dateutil; import Cn.bridgeli.sharesession.userinfo; import org.apache.commons.lan org.slf4j.loggerfactory; import org.springframework.http.server.serverhttprequest; import org.springframework.http.server.serverhttpresponse; import org.springframework.web.context.request.requestContexthEder; org.springframework.web.context.request.servletRequestAttributes; import org.springframework.web.socket.websockethandler; import org.springframework.web.socket.server.support.httpSessionHandshakeInterceptor; Import Java.util.Date; Importer Java.Ulil. @Description: Créez une interface de poignée de main * @Date: 16-3-3 * / classe publique HandshakeInterceptor étend httpSessionhandshakeInterceptor {private static final logger = loggerfactory.getLogger (HandshakeInterceptor.class); @ OverRidepublic Boolean Répondre (serverhttprequest demande, serveur, serveur de réponse, serverhttprequest requête, serveur, serveur de réponse, serveurhttprequest requête, serveur, serveur de serveur, ServerHakeShake Wshandler, map <string, object> attributs) lève une exception {logger.info ("avant de créer une poignée de main ..."); servletRequestAttributes attrs = (servLetRequestAttributes) requestContexTholder.getRequestAttributes (); userInfo curruser = usermanager. new Usersocketvo (); String e-mail = ""; if (null! = currusers) {email = curruser.getEmail ();} if (stringUtils.isblank (e-mail)) {email = dateUtil.date2string (new Date ());} usersocketvofvo.seTuseMail (e-mail); attributs.put ("Session_User", UsersocketVo); return super.beforeHandshake (demande, réponse, wshandler, attributs);} @ OverRidepublic void Afterhandshake (ServerHttpRequest Request, serverHttpResponse Response, WebSockethandler wshandler, exception ex) {Logger.info ("après avoir créé la poignée de main ..."); Super.AfterHandshake (demande, réponse, wshandler, ex);Parce que je ne comprends pas très bien, je garde le code d'origine dans la mesure maximale. Il s'agit en fait de supprimer l'utilisateur de connexion actuel à partir d'une seule connexion, de le convertir en un objet UsersocketVo et de le mettre sur la carte. Jetons donc un coup d'œil à la définition de l'objet Usersocketvo
4. Définition de Usersocketvo
Package cn.bridgeli.websocket; import org.springframework.web.socket.websocketSession; import java.util.date; / *** @description: entité de connexion de socket utilisateur * @date: 16-3-7 * / public class usersocketvo {private String userEmailwail; // e-mail utilisateur Date privée de connexion en temps; // Heure de connexion réussie Date privée PrérequestTime; // Dernier temps de demande Date privée NewRequestTime; // Nouveau heure de demande Date privée LastSendTime = new Date (); // la dernière heure d'envoi du message de suppression Date privée LastTaskSendTime = new Date (); // le dernier temps d'envoi de la tâche en attente privative WebSocketSession WebSocketSession; // La WSSESSE correspondant à l'utilisateur ne cache que une par défaut // getxx et setxx}Le plus important est la propriété WebSocketSession, que nous utiliserons plus tard
5. Implémentation de WebSocketpoint
package cn.bridgeli.websocket; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.beans.factory.annotation.autowired; import org.springframework.web.socket.closestatue; import org.spring org.springframework.web.socket.websocketSession; import org.springframework.web.socket.handler.textwebsockethandler; / *** @description: WebSocket Processing Class * @Date: 16-3-3 * / public classagedPoint étend TextWebSockethandler {private static Logger Logger = Public ClassOnDpoint. LoggerFactory.getLogger (WebSocketSendPoint.class); @ AutowiredPrivate NewsListenerImpl NewsListener; @OverRideProtected void HandleTextMessage (Session WebSocketSession, Message TextMessage) exception {newhandleTextMessage (Session, Message); TextMessage AT Server "); session.SendMessage (returnMessage);} / *** @description: Après avoir établi la connexion * @param session * @throws exception * / @ OverRidepublic void AfterConnectionStablished (WebSocketSession Session) lance l'exception {usersocketVo UsersocketSocketVO = (UsersocketVo) session.getAttributes (). Get (" Session_USER "); if (null! = UsersocketVo) {UsersocketVo.setwebsocketSession (session); if (wssessionLocalCache.exists (Usersocketvo.getUserEmail ())) {WSSessionLocalCache.Remove (UsersocketVo.getUserEmail ());} WSSessionLocalCache.put (UsersocketVo.getUserEremail (),,, Usersocketvo); newsListener.AfterConnectionEstAlled (usersocketvo.getUserEmail ());} logger.info ("socket a réussi à établir une connexion ..."); super.AfterConnectionEstabled (session);} @ overRidepublic void AfterConnectionClosed (Session WebSocketVo) (UsersocketVo) session.getAttributes (). Get ("session_user"); if (null! = Usersocketvo) {wssessionLocalCache.remove (usersocketvo.getUserEremail ());} logger.info ("socket a réussi à clôturer la connexion ..."); super.afterConnectionClosed (session, statut);}};6. Implémentation de WSSessionLocalCache
Package cn.bridgeli.websocket; import java.io.serializable; importer java.util.arraylist; import java.util.hashmap; import java.util.list; import java.util.map; / *** @description: Cache local websocketession instance * @date: 16-3-7 * / / classe publique WSSESCESSIONNESSECTIONS INSTERNES * @DATE: 16-3-7 * / Clasque public WSSESCESSIONNESSEMENTS INSTESTES * @Date: 16-3-7 * {Private Static Map <String, Usersocketvo> wsSessionCache = new HashMap <> (); public static boolean exists (String useremail) {if (! wssessioncache.containskey (userEmail)) {return false;} else {return true;}} public static void put (String Usemailwail, usersocketvo Usersocketvo) {WSSessionCache.put (Usemail, UsersocketVo);} public static usersocketvo get (String useremail) {return wsSessionCache.get (usemail);} public static voile retire ArrayList <> (wsSessionCache.Values ());}}Après avoir examiné sa mise en œuvre, l'effet est plus évident. Il stocke les dernières données de chaque USERSOCKETVO. En fait, notre implémentation WebSocket a été calculée ici, mais il y a toujours une classe de base (classe de Charlie sur la logique commerciale) qui n'a pas été mise en œuvre. Dans le prochain article, Spring Integrated Application Exemple (partie 2), nous verrons comment implémenter cette classe.
Introduction au protocole WebSocket
Le protocole WebSocket est une fonction importante dans le champ Web défini par la spécification RFC-6455: duplex complet, c'est-à-dire une communication bidirectionnelle entre le client et le serveur. C'est une fonctionnalité passionnante. L'industrie explore ce domaine depuis longtemps. Les technologies utilisées incluent Java Applet, XMLHTTPRequest, Adobe Flash, ActiveXObject, diverses technologies de comète, des événements d'envoi côté serveur, etc.
Il convient de comprendre qu'avant d'utiliser le protocole WebSocket, vous devez utiliser le protocole HTTP pour construire la poignée de main initiale. Cela repose sur un mécanisme - établir HTTP et demander des mises à niveau de protocole (ou des conversions de protocole). Lorsque le serveur est d'accord, il répondra au code d'état HTTP 101, indiquant qu'il accepte de changer le protocole. En supposant qu'une poignée de main réussie via des sockets TCP et la demande de mise à niveau du protocole HTTP sont passées, alors le client et le serveur peuvent se envoyer des messages.
Spring Framework 4.0 et au-dessus de l'introduction d'un nouveau module, à savoir le module Spring-WebSocket. Il prend en charge la communication WebSocket. Il est compatible avec la spécification de l'API Java WebSocket JSR-356, tout en offrant des fonctionnalités supplémentaires.
Dans quel scénario devez-vous utiliser WebSocket
Dans les applications Web, lorsque le client et le serveur doivent échanger des événements avec une fréquence plus élevée et une latence plus faible, il convient à WebSocket. Par conséquent, WebSocket convient aux scénarios d'application tels que la finance, le jeu et la collaboration.
Il peut ne pas convenir à d'autres scénarios d'application. Par exemple, un abonnement d'actualités nécessite des informations sur la rupture des nouvelles, et il est également acceptable d'utiliser un long sondage de plusieurs minutes d'intervalle, et le retard ici est acceptable.
Même dans les applications où une faible latence est requise, si le nombre de messages transmis est très faible (comme ceux de l'échec du réseau de surveillance), une technologie de sondage longue doit être prise en compte.
Uniquement dans les scénarios avec une communication de messages à faible latence et à haute fréquence, le choix du protocole WebSocket est très approprié. Même dans un tel scénario d'application, est-il toujours possible de choisir la communication WebSocket? Ou choisir la communication http repos?
La réponse est qu'elle dépendra des besoins de l'application. Cependant, il est également possible d'utiliser ces deux technologies en même temps pour mettre des données qui doivent être fréquemment échangées dans WebSocket et utiliser l'API REST comme technologie d'implémentation commerciale basée sur des processus. De plus, lorsqu'une certaines informations doit être diffusée à plusieurs clients de l'appel API REST, il peut également être implémenté via la connexion WebSocket.
Le Spring Framework fournit @Controller Annotation et @RestController Annotation, qui peuvent tous deux être utilisés pour le traitement des demandes HTTP et le traitement des messages WebSocket. De plus, les méthodes de traitement de la demande Spring MVC ou d'autres méthodes de traitement des demandes d'application peuvent facilement utiliser le protocole WebSocket pour diffuser des messages à tous les clients intéressés ou aux utilisateurs désignés.