Spring practice--Websocket integration and XML configuration

Introduction to WebSockets

WebSocket is a new protocol in HTML5. It realizes full-duplex communication between the browser and the server, which can better save server resources and bandwidth and achieve real-time communication. It is built on TCP and transmits data through TCP like HTTP, but the biggest difference between it and HTTP is:

  • WebSocket is a two-way communication protocol. After the connection is established, both the WebSocket server and the Browser/Client Agent can actively send or receive data to each other, just like Socket;
  • WebSocket requires a TCP-like client and server to connect through handshake, and can communicate with each other only after the connection is successful.

Integration example

This example demonstrates the broadcast mode of WebSocket, that is, when the server has a message, it will send the message to all Browser/Client Agents connected to the current endpoint

 1. maven import dependency package

    <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>

2. Write the configuration class for WebSocket

Annotation annotation configuration method (boot): WebSocketConfig.java

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 configuration method: spring-mvc.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: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>

 

3. Request Controller

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") + ">";
	}
}

 

4. The page webSocket.jsp

<%@ 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>

Rookie code example

<!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>

 

start and test

You can also open multiple browser windows to connect to the WebSocket server, click in one of the browser windows to get the server time, and the other two will also receive the message

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325224149&siteId=291194637