WebSocket 是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通讯,能更好的节省服务器资源和带宽并达到实时通信,它创建在 TCP 之上,同 HTTP 同样经过 TCP 来传输数据,可是它和 HTTP 最大不一样是:javascript
本示例为演示WebSocket的广播式模式,即服务端有消息时,会将消息发送给全部链接了当前endpoint的 Browser/Client Agenthtml
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <spring.version>4.3.8.RELEASE</spring.version> </properties> <dependencies> <!-- springmvc jar --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- WEBSOCKET的JAR --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-websocket</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-messaging</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; import org.springframework.web.socket.config.annotation.StompEndpointRegistry; @Configuration //开启对WebSocket的支持 @EnableWebSocketMessageBroker public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer{ /** * 注册一个STOMP协议的节点,并映射到指定的URL * @param registry */ @Override public void registerStompEndpoints(StompEndpointRegistry registry) { //注册一个STOMP的endpoint,并指定使用SockJS协议 registry.addEndpoint("/endpointSocket").withSockJS(); } /** * 配置消息代理 * @param registry */ @Override public void configureMessageBroker(MessageBrokerRegistry registry) { //配置一个广播式的消息代理 registry.enableSimpleBroker("/topic"); } }
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:websocket="http://www.springframework.org/schema/websocket" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.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.xsd"> <context:component-scan base-package="com"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/> </context:component-scan> <mvc:annotation-driven/> <mvc:resources mapping="/js/**" location="/js/"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/"/> <property name="suffix" value=".jsp"/> </bean> <!-- /app:客户端向服务端 发送的前缀 --> <websocket:message-broker application-destination-prefix="/app"> <websocket:stomp-endpoint path="/ws"> <websocket:sockjs/> </websocket:stomp-endpoint> <!-- 服务端向客户端 发送的前缀 --> <websocket:simple-broker prefix="/topic"/> </websocket:message-broker> </beans>
import java.util.Map; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.handler.annotation.SendTo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; /** * 由客户端触发,并接受服务器发送信息的例子 */ @Controller public class MessageController { @RequestMapping(value = "/websocket", method = { RequestMethod.GET }) public String toHello() { System.out.println("messageController ----> tohello()"); return "websocket"; //定位到页面 } @MessageMapping("/greeting") @SendTo("/topic/greetings") public String greeting(Map<String, Object> message) throws Exception { System.out.println("MessageController====================================>客户端链接"); return "服务器返回: Hello,客户端输入信息< " + message.get("name") + ">"; } }
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <%@ page session="false"%> <% String path = request.getContextPath(); // path = "/travel" String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/"; %> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Spring + WebSocket Hello world例子</title> <script src="<%=basePath%>js/sockjs-1.1.1.min.js"></script> <script src="<%=basePath%>js/stomp-2.3.4.min.js"></script> <script src="<%=basePath%>/js/jquery-1.10.2.js"></script> <script src="<%=basePath%>/js/jquery-ui-1.10.4.custom.js"></script> <script src="<%=basePath%>/js/jquery.json.js"></script> <script> //建立sockJS协议 var socket = new SockJS("<c:url value='/ws'/>"); var stompClient = Stomp.over(socket); //链接服务器 //stompClient.connect("guest", "guest", function() {}); 用户名和密码 stompClient.connect({}, function(frame) { //setConnected(true); $("#recFromServer").append("<br>" + "成功链接服务器.!"); console.log('Connected: ' + frame); window.alert('Connected: ' + frame); //subscribe:订阅一个主题,“/topic”前缀是在: stompClient.subscribe('/topic/greetings', function(greeting) { console.log(greeting.body); console.log("本身的操做!"); var content = JSON.parse(greeting.body).content; $("#recFromServer").append("<br>" + content); }); }); function sendMessage() { //发送信息给服务器 stompClient.send("/app/greeting", {}, JSON.stringify({ 'name' : $("#message").val() })); } </script> </head> <body> 输入名称:${basePath } <input id="message" type="text"> <input type="button" onclick="sendMessage()" value="发送到服务器"> <div id="recFromServer"></div> 测试方式: 用两个浏览器打开这个页面,而后一个页面提交信息,它能接收到服务器的数据,同时另外一个页面也能接收到服务器发送的数据。 </body> </html>
<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>My WebSocket</title> </head> <body> <input id="text" type="text" /> <button onclick="send()">Send</button> <button onclick="closeWebSocket()">Close</button> <div id="message"> </div> </body> <script type="text/javascript"> var websocket = null; //判断当前浏览器是否支持WebSocket if('WebSocket' in window){ //若是支持WebSocket,发起WebSocket链接 websocket = new WebSocket("ws://localhost:8088/websocket"); } else{ alert('Not support websocket') } //链接发生错误的回调方法 websocket.onerror = function(){ setMessageInnerHTML("error"); }; //链接成功创建的回调方法 websocket.onopen = function(event){ setMessageInnerHTML("open"); } //接收到消息的回调方法 websocket.onmessage = function(event){ setMessageInnerHTML(event.data); } //链接关闭的回调方法 websocket.onclose = function(){ setMessageInnerHTML("close"); } //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket链接,防止链接还没断开就关闭窗口,server端会抛异常。 window.onbeforeunload = function(){ //关闭链接 websocket.close(); } //将消息显示在网页上 function setMessageInnerHTML(innerHTML){ document.getElementById('message').innerHTML += innerHTML + '<br/>'; } //关闭链接 function closeWebSocket(){ websocket.close(); } //发送消息 function send(){ var message = document.getElementById('text').value; //发送消息 websocket.send(message); } </script> </html>
也可打开多个浏览器窗口链接到WebSocket服务端,在其中一个浏览器窗口中点击获取服务器时间,其余两个也将接收到消息html5