spring websocket 模擬發送消息

實現以下功能:

1、各個客戶端之間的消息互發;

2、客戶端向後臺發送消息;

3、後臺向客戶端發送消息


注:完整源代碼下載地址  http://download.csdn.net/detail/u010994277/9705588

代碼如下:

1)、配置處理器

/**
 * WebScoket配置處理器
 * 
 * @author www
 * @Date 2016年12月8日
 */
@Component
@EnableWebSocket
@Configuration  
@EnableWebMvc  
public class WebSocketConfig implements WebSocketConfigurer {

	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
		registry.addHandler(new MyWebSocketHandler(), "/portfolio2")// 添加一個處理器還有定義處理器的處理路徑
				.addInterceptors(new MyHandShakeInterceptor());
		registry.addHandler(new MyWebSocketHandler(), "/sockjs/portfolio2")// 添加一個處理器還有定義處理器的處理路徑
				.addInterceptors(new MyHandShakeInterceptor()).withSockJS();
	}

}
2、配置攔截器

/**
 * Socket建立連接(握手)和斷開
 * 
 * @author www
 * @Date 2016年12月8日
 */
public class MyHandShakeInterceptor implements HandshakeInterceptor {

	/**
     * 握手之前,若返回false,則不建立鏈接
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
            Map<String, Object> attributes) throws Exception {
        // TODO Auto-generated method stub
    	System.out.println("beforeHandshake-->");
    	if (request instanceof ServletServerHttpRequest) {
    		try {
    			ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
                HttpSession session = servletRequest.getServletRequest().getSession(false);
                if (session != null) {
                    String userId = (String) session.getAttribute(Constant.SESSION_USER_ID);
                    if(userId==null||userId.equals("")){
                    	throw new Exception("用戶ID爲空");
                    }
                    attributes.put(Constant.SESSION_USER_ID,userId);
                }else{
                	throw new Exception("session爲空");
                }
			} catch (Exception e) {
				attributes.put(Constant.SESSION_USER_ID,"test-user");
			}
        }
        return true;
    }

    /**
     * 握手之後
     */
    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
            Exception exception) {
        // TODO Auto-generated method stub
    	System.out.println("afterHandshake-->");
    }

3、socket處理器

/**
 * Socket處理器
 * 
 * @author www
 * @Date 2016年12月8日
 */
@Component
public class MyWebSocketHandler implements WebSocketHandler {

	public static final Map<String, WebSocketSession> userSocketSessionMap;

	static {
		userSocketSessionMap = new HashMap<String, WebSocketSession>();
	}

	/**
	 * webscoket建立好鏈接之後的處理函數
	 * 
	 * @param session
	 *            當前websocket的會話id,打開一個websocket通過都會生成唯一的一個會話,
	 *            可以通過該id進行發送消息到瀏覽器客戶端
	 */
	@Override
	public void afterConnectionEstablished(WebSocketSession session)
			throws Exception {
		// TODO Auto-generated method stub
		String uid = (String) session.getAttributes().get(Constant.SESSION_USER_ID);
		System.out.println("用戶ID:" + uid + ";已建立連接");
		// 每個鏈接來的客戶端都把WebSocketSession保存進來
		if (userSocketSessionMap.get(uid) == null) {
			userSocketSessionMap.put(uid, session);
		}else{
			userSocketSessionMap.remove(uid);
			userSocketSessionMap.put(uid, session);
		}
		
	}

	/**
	 * 客戶端發送服務器的消息時,的處理函數,在這裏收到消息之後可以分發消息
	 */
	@Override
	public void handleMessage(WebSocketSession session,
			WebSocketMessage<?> message) throws Exception {
		// TODO Auto-generated method stub
		Iterator<Map.Entry<String, WebSocketSession>> entries = userSocketSessionMap.entrySet().iterator();  
		while (entries.hasNext()) {  
		    Map.Entry<String, WebSocketSession> entry = entries.next();  
		    System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());  
		    if(entry.getKey().equals(session.getAttributes().get("userId"))){
		    	String msg = "後臺已收到信息[" + message.getPayload().toString()+ "];用戶ID爲:" + entry.getKey();
				System.out.println(msg);
				message = new TextMessage(msg);
				entry.getValue().sendMessage(message);
		    }
		}  
	}

	/**
	 * 消息傳輸過程中出現的異常處理函數
	 */
	@Override
	public void handleTransportError(WebSocketSession session,
			Throwable exception) throws Exception {
		// TODO Auto-generated method stub
		String userId=(String) session.getAttributes().get("userId");
		userSocketSessionMap.remove(userId);

	}

	/**
	 * websocket鏈接關閉的回調
	 */
	@Override
	public void afterConnectionClosed(WebSocketSession session,
			CloseStatus closeStatus) throws Exception {
		// TODO Auto-generated method stub
		String userId=(String) session.getAttributes().get("userId");
		userSocketSessionMap.remove(userId);
	}

	/**
	 * 是否支持處理拆分消息,返回true返回拆分消息
	 */
	@Override
	public boolean supportsPartialMessages() {
		// TODO Auto-generated method stub
		return false;
	}

	/**
	 * 給所有在線用戶發送消息
	 * 
	 * @param message
	 * @throws IOException
	 */
	public void broadcast(final String msg) throws IOException {
		final TextMessage message=new TextMessage(msg);
		Iterator<Entry<String, WebSocketSession>> it = userSocketSessionMap.entrySet().iterator();
		// 多線程羣發
		while (it.hasNext()) {

			final Entry<String, WebSocketSession> entry = it.next();

			if (entry.getValue().isOpen()) {
				// entry.getValue().sendMessage(message);
				new Thread(new Runnable() {

					public void run() {
						try {
							if (entry.getValue().isOpen()) {
								entry.getValue().sendMessage(message);
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
					}

				}).start();
			}

		}
	}

	/**
	 * 給某個用戶發送消息
	 * 
	 * @param userName
	 * @param message
	 * @throws IOException
	 */
	public void sendMessageToUser(String uid, String msg)
			throws IOException {
		TextMessage message=new TextMessage(msg);
		WebSocketSession session = userSocketSessionMap.get(uid);
		if (session != null && session.isOpen()) {
			session.sendMessage(message);
		}
	}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章