SpringBoot整合WebSocket,实现实时好友状态更新

1 WebSocket介绍

   服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,来实现真正的全双工通信,用户可以通过服务端的实时推送,在客户端能收到服务器实时消息推送;客户端一次请求WebSocket服务,将长久建立有效的连接。

2 WebSocket应用场景

 这次根据业务需要推送用户好友在线、离线、忙碌的状态推送,果断选择了WebSocket来实现,提升用户的体验效果,其他应用如弹幕、多玩家游戏、协同编辑、股票基金实时报价、体育实况更新等需要实时数据的场景。

3 WebSocket在SpringBoot中的应用

3.1 引入maven的配置


        
            org.springframework.boot
            spring-boot-starter-websocket
        
        
            org.springframework.boot
            spring-boot-starter-thymeleaf
        

3.2 配置

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

3.3 创建WebSocketServer消息处理类

import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;

@ServerEndpoint("/ws/staff")
@Component
public class WebSocketServer {
    @PostConstruct
    public void init() {
        System.out.println("websocker开始加载了。。");
    }

    private final static AtomicInteger onlineCount = new AtomicInteger(0);
    private static CopyOnWriteArraySet sessionSet = new CopyOnWriteArraySet();

    /**
     * 建立连接成功后调用
     */
    @OnOpen
    public void onOpen(Session session) {
        sessionSet.add(session);
        int cnt = onlineCount.incrementAndGet();
        System.out.println("第" + cnt + "个建立连接成功了。。");
    }

    /**
     * 连接关闭调用
     *
     * @param session
     */
    @OnClose
    public void onClose(Session session) {
        sessionSet.remove(session);
        onlineCount.decrementAndGet();
        System.out.println("关闭一个连接。。");
    }

    @OnError
    public void onError(Session session, Throwable e) {
        System.out.println(session.getId() + "连接出错了。。");
    }

    @OnMessage
    public void sendMession(Session session, String message) {
        sendMessage(session, "收到消息,消息内容:" + message);
    }

    public static void sendMessage(Session session, String message) {
        try {
            session.getBasicRemote().sendText(String.format("%s (From Server,Session ID=%s)", message, session.getId()));
        } catch (Exception e) {

        }
    }

    /**
     * 群发消息
     *
     * @param message
     * @throws IOException
     */
    public static void broadCastInfo(String message) throws IOException {
        for (Session session : sessionSet) {
            if (session.isOpen()) {
                sendMessage(session, message);
            }
        }
    }

    /**
     * 指定Session发送消息
     *
     * @param sessionId
     * @param message
     * @throws IOException
     */
    public static void sendMessage(String message, String sessionId) throws IOException {
        Session session = null;
        for (Session s : sessionSet) {
            if (s.getId().equals(sessionId)) {
                session = s;
                break;
            }
        }
        if (session != null) {
            sendMessage(session, message);
        } else {
            System.out.println("没有找到你指定ID的会话:{}" + sessionId);
        }
    }
}

3.4 创建WebSocketController,用来接收客户端请求

import com.apabi.av.model.WebSocketServer;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;

@RestController
@RequestMapping("/webSocketApi")
public class WebSocketController {
    /**
     * 群发消息内容
     * @param message
     * @return
     */
    @RequestMapping(value="/sendAll", method= RequestMethod.GET)
    public String sendAllMessage(@RequestParam(required=true) String message){
        try {
            WebSocketServer.broadCastInfo(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "ok";
    }

    /**
     * 指定会话ID发消息
     * @param message 消息内容
     * @param id 连接会话ID
     * @return
     */
    @RequestMapping(value="/sendOne", method=RequestMethod.GET)
    public String sendOneMessage(@RequestParam(required=true) String message,@RequestParam(required=true) String id){
        try {
            WebSocketServer.sendMessage(message,id);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "ok";
    }

}

3.5 在项目目录/resources/templates下创建index.html文件




    
    websocket测试
    



WebSocket测试,在控制台查看测试信息输出!

3.6 启动项目,访问index.html,http://127.0.0.1:8081/,创建与服务器的连接,发送请求http://127.0.0.1:8081/webSocketApi/sendOne?message=测试单人通信&id=0,查看index.html页面控制台打印信息

你可能感兴趣的:(SpringBoot)