WebSocket(二)——spring websocket實現前后端通信(服務器端)


步驟一:添加maven依賴
步驟二:編輯SpringWebSocketConfig,xml配置和使用注解兩種方式。
registerWebSocketHandlers:這個方法是向spring容器注冊一個handler地址,我把他理解成requestMapping。
addInterceptors:攔截器,當建立websocket連接的時候,我們可以通過繼承spring的HttpSessionHandshakeInterceptor來搞事情。
setAllowedOrigins:跨域設置,*表示所有域名都可以,不限制, 域包括ip:port, 指定*可以是任意的域名,不加的話默認localhost+本服務端口
withSockJS: 這個是應對瀏覽器不支持websocket協議的時候降級為輪詢的處理。
package com.ssm.websocket;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;
/*
@Configuration的作用
聲明當前類是一個配置類
@Configuration不可以是final類型;
@Configuration不可以是匿名類;
嵌套的configuration必須是靜態類。
@EnableWebSocket  聲明該類支持WebSocket
 */
@Configuration
@EnableWebSocket
public class MySocketConfig implements WebSocketConfigurer {

    //websocket入口,允許訪問的域、注冊Handler、SockJs支持和攔截器。
    
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(myHandler(),"/websocket")//入口路徑為websocket
                .addInterceptors(new SpringWebSocketHandler())
                .setAllowedOrigins("*");
        //setAllowedOrigins()方法的支持spring4.1.5之后的版本才支持
        //setAllowedOrigins(String... val),允許指定的域名或IP(含端口號)建立長連接,
        // 可以只設置允許自家域名訪問,如果不限時使用"*"號,如果指定了域名,
        // 則必須要以http或https開頭。
    }

    @Bean
    public WebSocketHandler myHandler(){
        return new MySocketHandler();
    }

    @Bean
    public HttpSessionHandshakeInterceptor myHandlerInterceptor(){
        return new SpringWebSocketHandler();
    }

}
步驟三:編寫SpringWebSocketHandlerInterceptor    
這個是創建websocket連接是的攔截器,記錄建立連接的用戶的session以便根據不同session來通信
package com.ssm.websocket;

import com.lingdian.pojo.User;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.*;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

import javax.servlet.http.HttpSession;
import java.util.Map;
/*
握手攔截器類
 */
public class SpringWebSocketHandler extends HttpSessionHandshakeInterceptor {

    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
        System.out.println("Before Handshake");
        //在握手之前將HttpSession中的用戶,copy放到WebSocket Session中
        if (request instanceof ServletServerHttpRequest){
            ServletServerHttpRequest servletServerHttpRequest=
                    (ServletServerHttpRequest) request;
            HttpSession session=
                    servletServerHttpRequest.getServletRequest().getSession(true);
            if (null!=session){
               User user=(User)session.getAttribute("user");
               //WebSocket Session
               attributes.put("user",user);
            }
        }
        return super.beforeHandshake(request,response,wsHandler,attributes);
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception ex) {
        super.afterHandshake(request, response, wsHandler, ex);
    }


}

步驟四:編寫SpringWebSocketHandler 

 
package com.ssm.websocket;

import com.lingdian.pojo.Message;
import com.lingdian.pojo.User;
import com.lingdian.service.MessageService;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CopyOnWriteArraySet;
/***
 * 消息處理類
 */
public class MySocketHandler extends TextWebSocketHandler {

    //使用CopyOnWriteArraySet,保證線程安全,當一個用戶
    // 退出時,這邊的用戶查看用戶列表時不會出現安全失敗
    private static CopyOnWriteArraySet<WebSocketSession> users=new CopyOnWriteArraySet<WebSocketSession>();;


    @Resource
    private MessageService messageService;

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        //super.handleTextMessage(session, message);
        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = sd.format(new Date());
        //從 WebSocket Session中取得用戶
        User user=(User) session.getAttributes().get("user");
        Message message1=new Message();
        message1.setUid(user.getId());
        message1.setMessage(message.getPayload());
        message1.setSendTime(new Date());
        //將消息保存到數據庫
        messageService.insertMessage(message1);
        //封裝要輸出的消息到TextMessage,姓名,時間,消息
        TextMessage returnMessage =
                new TextMessage(user.getName()+":" +
                        ""+time+"<br/>"+message.getPayload());
        for (WebSocketSession session1 : users) {
            try{
                //使用sendMessage()方法輸出消息到客戶端
                session1.sendMessage(returnMessage);
            }catch (Exception e){
                e.printStackTrace();
                continue;
            }

        }
    }

    /**
     * 連接成功時候,會觸發頁面上onopen方法
     * 加入一個用戶 add進集合
     * @param session
     * @throws Exception
     */
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        users.add(session);
        System.out.println("connect to the websocket success......當前數量:"+users.size());

    }

    /**
     * 關閉鏈接時觸發,當用戶退出時,將用戶從集合remove
     * @param session
     * @param status
     * @throws Exception
     */
    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
        users.remove(session);
        System.out.println("剩余在線用戶"+users.size());
    }

    public static CopyOnWriteArraySet<WebSocketSession> getUsers() {
        return users;
    }

    public static void setUsers(CopyOnWriteArraySet<WebSocketSession> users) {
        MySocketHandler.users = users;
    }

    public MessageService getMessageService() {
        return messageService;
    }

    public void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM