Spring Boot整合Socket

會Coding的猴子發表於2018-08-19

使用WebSocket模組

  • 匯入spring-boot-starter-websocket依賴
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
複製程式碼
  • 編寫WebSocket配置類
package cn.java2016.demo.config;

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

@Configuration
public class WebSocketConfiguration {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
    	return new ServerEndpointExporter();
    }
}
複製程式碼
  • 配置WebSocket處理類
package cn.java2016.demo.component;

import java.io.IOException;

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

import org.springframework.stereotype.Component;

@ServerEndpoint("/websocket")   // 訪問路徑: ws://localhost:8080/websocket
@Component
public class WebSocketServer {

    // 第一次連線呼叫
    @OnOpen
    public void open(Session session) throws IOException {
    	System.out.println("connect..");
    	session.getBasicRemote().sendText("server: 登陸成功!");
    }
    
    // 關閉連線呼叫
    @OnClose
    public void close() {
    	System.out.println("disconnect..");
    }
    
    // 接收訊息
    @OnMessage
    public void message(String message, Session session) {
    	System.out.println("client send: " + message);
    }
}
複製程式碼
  • 前端頁面程式碼
// 判斷瀏覽器是否支援WebSocket
if ('WebSocket' in window) {
    var socket = new WebSocket("ws://localhost:8080/websocket")
    // 第一次連線
    socket.onopen = function (ev) {
        console.log(ev)
        // 向伺服器傳送訊息
        socket.send('sfsd')
    }
    // 連線被關閉: 瀏覽器重新整理 | 瀏覽器關閉 | 伺服器關閉
    socket.onclose = function (ev) {
        console.log(ev)
    }
    // 連線錯誤
    socket.onerror = function (ev) {
        console.log(ev)
    }
    // 接收訊息
    socket.onmessage = function (ev) {
        // 列印訊息
        console.log(ev.data)
    }
}
複製程式碼

使用SocketIO模組

  • 引入SocketIO依賴
<dependency>
    <groupId>com.corundumstudio.socketio</groupId>
    <artifactId>netty-socketio</artifactId>
    <version>1.7.16</version>
</dependency>
複製程式碼
  • 加入SocketIO配置類
package cn.java2016.demo.config;

import org.springframework.boot.CommandLineRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner;

@Configuration
public class SocketIOConfiguration implements CommandLineRunner{
    
    @Bean
    public SocketIOServer socketIOServer() {
    	com.corundumstudio.socketio.Configuration conf = new com.corundumstudio.socketio.Configuration();
    	// 設定ip地址和埠
    	conf.setHostname("localhost");
    	conf.setPort(8081); 
    	return new SocketIOServer(conf);
    }
    
    @Bean
    public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketIOServer) {
    	return new SpringAnnotationScanner(socketIOServer);
    }
    
    @Override
    public void run(String... args) throws Exception {
        // 啟動socket服務
    	socketIOServer().start();
    }
}
複製程式碼
  • 配置SocketIO服務元件
package cn.java2016.demo.component;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.corundumstudio.socketio.SocketIOClient;
import com.corundumstudio.socketio.SocketIOServer;
import com.corundumstudio.socketio.annotation.OnConnect;
import com.corundumstudio.socketio.annotation.OnDisconnect;
import com.corundumstudio.socketio.annotation.OnEvent;

import cn.java2016.demo.pojo.User;

/**
 * WebSocket服務不會熱載入,需要手動重啟
 * @author Administrator
 */
@Component
public class SocketServer {
	
    @Autowired
    public SocketIOServer socketServer;
    
    // 連線開啟
    @OnConnect
    public void connect(SocketIOClient client) {
    	System.out.println("socketio connect..");
    	client.sendEvent("data", "連線成功!");
    //		socketServer.getClient(client.getSessionId()).sendEvent("data", "sdfsdf");
    //		System.out.println(client.getSessionId());
    }
    
    // 連線關閉
    @OnDisconnect
    public void disconnect(SocketIOClient client) {
    	System.out.println("socketio disconnect..");
    }
    
    // 監聽login事件
    @OnEvent("login")
    public void login(SocketIOClient client, String name) {
    	System.out.println("login.." + name);
    //		socketServer.getClient(uuid)socketClient.sendEvent("data", new User(name, age));
    	client.sendEvent("data", "login success2..");
    }
    
    // 監聽register事件, 自動注入pojo類,用法和SpringMvc基本一致
    @OnEvent("register")
    public void register(User user, SocketIOClient client) {
    	System.out.println("register..");
    	System.out.println(user);
    	// 傳送訊息
    	client.sendEvent("data", new User(user.getName(), user.getAge()).toString());
    //		socketServer.getClient(client.getSessionId()).sendEvent("data", new User(user.getName(), user.getAge()));
    }
}
複製程式碼
  • 前臺程式碼,引入socketio依賴
<script src="https://cdn.bootcss.com/socket.io/2.1.1/socket.io.dev.js"></script>
複製程式碼
var socket = io("ws://localhost:8081")
// 監聽連線事件
socket.on('connect', function () {
    console.log('connection..')
})
// 關閉連線
socket.on('disconnect', function () {
    console.log('connection close..')
})
// 監聽data事件
socket.on('data', function (data) {
    console.log(data)
})
// 觸發事件,並傳遞json資料,在後臺會自動被注入成User物件
socket.emit("register", {name: "張三", age: 18})
socket.emit('login')
複製程式碼

注:Spring Boot DevTools熱載入不會重啟socket服務,需要手動重啟

相關文章