Simple introduction to springboot and websocket

1. What is the websocket protocol?

WebSocket is a protocol in HTML5. It was born in order to solve the problem that the browser must go through a long rotation training for the client to initiate multiple http requests to the server resource browser. It implements multiplexing and it is full-duplex communication. The customer service terminal and the browser can send information at the same time under the webSocket protocol.

2. Different from http protocol

the difference http websocket
Link method http1.0 is a normal http request, usually a short link, one request, three handshake, and immediately disconnected after completion In fact, websocket is an upgrade of the http protocol. The http1.1 version defaults to long links. Long links represent: once a link, the link is maintained for a certain period of time, and the tcp is not disconnected. Both parties can communicate instantly. It is a full-duplex communication protocol.
Scenes The http protocol is more suitable for ordinary file requests, not for instant messaging. Generally, we need to get timely information. Through the http method, we need to continuously poll, which consumes a lot of network resources. websocket is more suitable for instant communication without constant polling, one link is effective for a long time

3. Code implementation

3.1 Import pom.xml

<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.1.RELEASE</version>
	</parent>
	<groupId>com.liuhao.springboot</groupId>
	<artifactId>springboot-websocket</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>springboot-websocket</name>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<!-- websocket依赖 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-websocket</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-thymeleaf</artifactId>
		</dependency>
	</dependencies>
</project>

3.2 Writing the websocketCofig class

package com.liuhao.application.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    
    

	/**
	 * @return
	 */
	@Bean
	public ServerEndpointExporter serverEndpointExporter() {
    
    

		return new ServerEndpointExporter();
	}
}

3.3 implement websocket protocol class

package com.liuhao.application.pojo;

import java.io.IOException;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import org.springframework.stereotype.Component;

@ServerEndpoint("/websocket/{sid}")
@Component
public class WebSocketServer {
    
    

	// session 会话集合
	private static ConcurrentHashMap<String, Session> map = new ConcurrentHashMap<String, Session>();

	// 当前会话
	private Session session;
	// sid
	private String sid = "";

	/**
	 * 连接
	 * 
	 * @param session 服务器与客户端建立建立连接,生成会话
	 * @param sid     客户端的唯一id
	 */
	@OnOpen
	public void onOpen(Session session, @PathParam("sid") String sid) {
    
    
		this.session = session;
		this.sid = sid;
		System.out.println("有一个连接sid:" + this.sid);
		this.map.put(this.sid, this.session);
	}

	/**
	 * 关闭当前会话
	 */
	@OnClose
	public void onClose() {
    
    
		try {
    
    
			// 从名单中清楚
			this.map.remove(this.sid);
			// 关闭会话
			this.session.close();

			System.out.println("sid:" + sid + "会话被关闭,移除");
		} catch (IOException e) {
    
    
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 接受消息
	 * 
	 * @param message 接受到的消息
	 */
	@OnMessage
	public void onMessage(String message) {
    
    
		try {
    
    
			System.out.println("message:" + message);

			// 广播消息
			for (Entry<String, Session> entry : map.entrySet()) {
    
    
				entry.getValue().getBasicRemote().sendText(message);
			}
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
	}

	/**
	 * 发送消息
	 * 
	 * @param massage 需要发送消息
	 */
	public void sendMassage(String massage) {
    
    
		try {
    
    
			this.session.getBasicRemote().sendText(massage);
		} catch (Exception e) {
    
    
			e.printStackTrace();
		}
	}
}

3.4 Front-end page

<!DOCTYPE html>
<html lang="zh-CN">
	<head>
		<meta charset="utf-8">
		<meta http-equiv="X-UA-Compatible" content="IE=edge">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
		<title>Bootstrap 101 Template</title>
		<link rel="stylesheet" type="text/css" href="../css/bootstrap.css" />
		<script src="../js/Vue2.6.11.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<div id="app">
			<div class="container">
				<form action="" method="">
					<div class="row">
						<div class="form-group col-md-6">
							<label>信息展示:</label>
							<textarea class="form-control" rows="10" cols="" v-model="showContent"></textarea>
						</div>
						<div class="col-md-6">
							<div class="row">
								<div class="form-group col-md-12">
									<label>发送人ID:</label>
									<input type="text" class="form-control" name="" v-model="id" />
								</div>
							</div>
							<div class="row">
								<div class="form-group col-md-12">
									<label>发送信息:</label>
									<textarea class="form-control" rows="6" cols="" v-model="sendContent"></textarea>
								</div>
							</div>
							<div class="row">
								<div class="form-group col-md-6">
									<button type="button" class="btn btn-primary btn-block" @click="sendMsg()">点击发送</button>
								</div>
								<div class="form-group col-md-6">
									<button type="button" class="btn btn-danger btn-block" @click="connect()">连接</button>
								</div>
							</div>
						</div>
					</div>
				</form>
			</div>
		</div>

		<script type="text/javascript">
			var vm = new Vue({
     
     
				el: '#app',
				data: {
     
     
					id: '',
					showContent: '',
					sendContent: '',
					socket: null
				},
				methods: {
     
     
					connect: function() {
     
     
						var lsocket;
						if (typeof(WebSocket) == "undefined") {
     
     
							console.log("您的浏览器不支持WebSocket,请更换浏览器");
							return;
						} else {
     
     
							console.log("您的浏览器支持WebSocket");
							if (this.id.trim() == "") {
     
     
								alert('连接之前必须指定唯一ID')
								return
							}

							lsocket = new WebSocket("ws://localhost:8080/websocket/" + this.id)
							this.socket = lsocket

							this.socket.onopen = function() {
     
     
								console.log('连接已开放')
							}
							this.socket.onerror = function() {
     
     
								alert('websocket出现error')
							}
							this.socket.onmessage = function(msg) {
     
     
								console.log(msg)
								vm.showContent += msg.data
							}
						}
					},
					sendMsg: function() {
     
     
						if(this.sendContent.trim()==""||this.socket==null)
						{
     
     
							alert('不能发送空的信息哦,发送信息前,要先连接')
							return 
						}
						this.socket.send(this.sendContent)
						this.sendContent=''
					}
				},
				created: function() {
     
     

				}
			})
		</script>
	</body>
</html>

3.5App startup class

package com.liuhao.application;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class App {
    
    

	public static void main(String[] args) {
    
    
		SpringApplication.run(App.class, args);
	}
}

Guess you like

Origin blog.csdn.net/qq_42418169/article/details/109178412