關(guān)于原理我就不啰嗦了。自己在網(wǎng)上搜一下就知道了。
1.注冊(cè)服務(wù):
package com.tw.webSocket;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.config.annotation.EnableWebSocket;import org.springframework.web.socket.config.annotation.WebSocketConfigurer;import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;@Configuration@EnableWebSocketpublic class WebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer{ @Override public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { registry.addHandler(systemWebSocketHandler(), "/webSocketServer").addInterceptors(new MyHandshakeInterceptor()); System.out.println("registed!"); registry.addHandler(systemWebSocketHandler(), "/sockjs/webSocketServer").addInterceptors(new MyHandshakeInterceptor()).withSockJS(); } @Bean public WebSocketHandler systemWebSocketHandler(){ return new SystemWebSocketHandler(); }}我們注冊(cè)兩種:ws 和http 實(shí)現(xiàn)websocket。
2.繼承握手?jǐn)r截器:
package com.tw.webSocket;import java.util.Map;import javax.servlet.http.HttpSession;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.http.server.ServletServerHttpRequest;import org.springframework.stereotype.Component;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;import com.tw.entity.sys.User;@Componentpublic class MyHandshakeInterceptor extends HttpSessionHandshakeInterceptor{ @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler, Map<String, Object> map) throws Exception { if (request instanceof ServletServerHttpRequest) { ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; HttpSession session = servletRequest.getServletRequest().getSession(false); if (session!=null) { System.out.println("ok"); User u = (User) session.getAttribute("U"); map.put("username", u.getName()); } } return true; } @Override public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) { }}這里是拿到在線的用戶。
3.實(shí)現(xiàn)服務(wù)端的消息接受和推送:
package com.tw.webSocket;import java.io.IOException;import java.util.ArrayList;import org.springframework.stereotype.Component;import org.springframework.web.socket.CloseStatus;import org.springframework.web.socket.TextMessage;import org.springframework.web.socket.WebSocketHandler;import org.springframework.web.socket.WebSocketMessage;import org.springframework.web.socket.WebSocketSession;@Componentpublic class SystemWebSocketHandler implements WebSocketHandler{ private static final ArrayList<WebSocketSession> users; static{ users = new ArrayList<WebSocketSession>(); } public SystemWebSocketHandler(){ } @Override public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception { users.remove(session); } @Override public void afterConnectionEstablished(WebSocketSession session) throws Exception { System.out.println("Server:cennected OK!"); users.add(session); } @Override public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception { TextMessage tm = new TextMessage(message.getPayload()+""); System.out.println(message.getPayload()); session.sendMessage(tm); } @Override public void handleTransportError(WebSocketSession session, Throwable throwable) throws Exception { if (session.isOpen()) { session.close(); } users.remove(session); } @Override public boolean supportsPartialMessages() { return false; } /** * 給所有在線用戶發(fā)送消息 * @param message */ public void sendMessageToUsers(TextMessage message) { for (WebSocketSession user : users) { if (user.isOpen()) { try { user.sendMessage(message); } catch (IOException e) { e.printStackTrace(); } } } } public void sendMessageToUser(String username,TextMessage message) { for (WebSocketSession user : users) { if (user.getAttributes().get("username").equals(username)) { try { if (user.isOpen()) { user.sendMessage(message); } } catch (IOException e) { e.printStackTrace(); } break; } } }}4.配置文件applicationContext.xml:
<context:annotation-config/>
<context:component-scan base-package="com.tw"/>
tw-servlet.xml:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd"> <context:component-scan base-package="com.tw.controller" /> <mvc:annotation-driven> <mvc:message-converters register-defaults="true"> <!-- 避免IE執(zhí)行AJAX時(shí),返回JSON出現(xiàn)下載文件 --> <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven> <!-- 啟動(dòng)Spring MVC的注解功能,完成請(qǐng)求和注解POJO的映射 --> <!-- <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="fastJsonHttpMessageConverter" /> </list> </property> </bean> --> <!-- 對(duì)模型視圖名稱的解析,即在模型視圖名稱添加前后綴 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/"></property> <property name="suffix" value=".jsp"></property> </bean> <!-- 支持上傳文件 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/> <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.tw.interceptor.PermissionAnnotationInterceptor"> <property name="excludeUrls"> <list> <value>/menu/init</value> <value>/menu/tree</value> <value>/user/login</value> <value>/user/logout</value> <value>/user/init</value> <value>/user/reg</value> <value>/user/regu</value> <value>/permission/init</value> <value>/index</value> <value>/pcrimg</value> <value>/init</value> </list> </property> </bean> </mvc:interceptor> </mvc:interceptors></beans>這里就加了個(gè):xmlns:websocket="http://www.springframework.org/schema/websocket"
http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket-4.1.xsd
web.xml 沒(méi)有任何特殊的。
5.在需要顯示消息的頁(yè)面這樣做:
<%@ page language="java" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>hi</title> </head> <body> dsdsds <span id="msgcount"></span> <script type="text/javascript" charset="UTF-8" src="${pageContext.request.contextPath}/js/jquery.min.js"></script> <script type="text/javascript" charset="UTF-8" src="${pageContext.request.contextPath}/js/sockjs-0.3.4.min.js"></script><script type="text/javascript">var websocket;if ('WebSocket' in window) { websocket = new WebSocket("ws://localhost:8080/tw/webSocketServer");} else { websocket = new SockJS("http://localhost:8080/tw/sockjs/webSocketServer");}websocket.onopen = function (evnt) {};websocket.onmessage = function (evnt) { $("#msgcount").html("(<font color='red'>"+evnt.data+"</font>)")};websocket.onerror = function (evnt) {};websocket.onclose = function (evnt) {}</script> </body></html>6.在controller里面就可以這樣調(diào)用了:
@Bean public SystemWebSocketHandler systemWebSocketHandler(){ return new SystemWebSocketHandler(); } @RequestMapping("/auditing") @ResponseBody public String auditing(HttpServletRequest request){ //無(wú)關(guān)代碼都省略了 systemWebSocketHandler().sendMessageToUser("admin", new TextMessage("你好")); return ""; }
這些代碼就可以放在自己需要的任何地方了。
基本就這樣了,你想做web聊天室 或 web的網(wǎng)頁(yè)消息提示都可以。
聯(lián)系客服