websocket实时推送例子

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011410254/article/details/79216642

demo基于spring框架来写的。

第一步:自己搭建一个springmvc项目,很简单,网上百度都有;pom文件添加以下:

 <!-- WebSocket -->
      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-websocket</artifactId>
         <version>4.2.4.RELEASE</version>
      </dependency>


      <dependency>
         <groupId>org.springframework</groupId>
         <artifactId>spring-messaging</artifactId>
         <version>4.2.4.RELEASE</version>
      </dependency>
我的spring版本是4.2.4的,所以websocket也是4.2.4的;websocket最好和spring版本保持一致

第二步:编写消息处理器


/**
 * Project Name:springRabbitMQ
 * File Name:MyMessageHandler.java
 * Package Name:com.zsy.websocket
 * Date:2018年1月31日上午11:10:03
 * Copyright (c) 2018, zhaoshouyun All Rights Reserved.
 *
 */

package com.zsy.websocket;

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

import org.apache.commons.lang3.StringUtils;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;

/**
 * ClassName: MyMessageHandler 
 * Function: 实现webscoket接口
 * date: 2018年1月31日 上午11:10:03 
 * @author zhaoshouyun
 * @version 
 * @since JDK 1.7
 */
public class MyMessageHandler implements WebSocketHandler {
    //用户key
	public static final String USER_KEY = "current_user";

	/**
	 * userMap:存储用户连接webscoket信息
	 * @since JDK 1.7
	 */
	private final static Map<String, WebSocketSession> userMap;
	static {
		userMap = new ConcurrentHashMap<String,WebSocketSession>(30);
	}
	/**
	 * 关闭websocket时调用该方法
	 * @see org.springframework.web.socket.WebSocketHandler#afterConnectionClosed(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.CloseStatus)
	 */
	@Override
	public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
            String userId = this.getUserId(session);
            if(StringUtils.isNoneBlank(userId)){
            	userMap.remove(userId);
            	System.err.println("该" + userId +"用户已成功关闭");
            }else{
            	System.err.println("关闭时,获取用户id为空");
            }

	}

	/**
	 * 建立websocket连接时调用该方法
	 * @see org.springframework.web.socket.WebSocketHandler#afterConnectionEstablished(org.springframework.web.socket.WebSocketSession)
	 */
	@Override
	public void afterConnectionEstablished(WebSocketSession session) throws Exception {
		String userId = this.getUserId(session);
		if(StringUtils.isNoneBlank(userId)){
			userMap.put(userId, session);
			session.sendMessage(new TextMessage("建立WebSocket连接成功!"));
		}

	}

	/**
	 * 客户端调用websocket.send时候,会调用该方法,进行数据通信
	 * @see org.springframework.web.socket.WebSocketHandler#handleMessage(org.springframework.web.socket.WebSocketSession, org.springframework.web.socket.WebSocketMessage)
	 */
	@Override
	public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
              String msg = message.toString();
              String userId = this.getUserId(session);
              System.err.println("该"+userId+"用户发送的消息是:"+msg);
              message = new TextMessage("服务端已经接收到消息,msg="+msg);
              session.sendMessage(message);

	}

	/**
	 * 传输过程出现异常时,调用该方法
	 * @see org.springframework.web.socket.WebSocketHandler#handleTransportError(org.springframework.web.socket.WebSocketSession, java.lang.Throwable)
	 */
	@Override
	public void handleTransportError(WebSocketSession session, Throwable e) throws Exception {
		WebSocketMessage<String> message = new TextMessage("异常信息:"+e.getMessage());
        session.sendMessage(message);
	}

	/**
	 * 
	 * @see org.springframework.web.socket.WebSocketHandler#supportsPartialMessages()
	 */
	@Override
	public boolean supportsPartialMessages() {

		return false;
	}
	
	/**
	 * sendMessageToUser:发给指定用户
	 * @author zhaoshouyun
	 * @param userId
	 * @param contents
	 * @since JDK 1.7
	 */
	public void sendMessageToUser(String userId,String contents) {
        WebSocketSession session = userMap.get(userId);
        if(session !=null && session.isOpen()) {
            try {
            					TextMessage message = new TextMessage(contents);
                session.sendMessage(message);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
	
	 /**
	 * sendMessageToAllUsers:发给所有的用户
	 * @author zhaoshouyun
	 * @param contents
	 * @since JDK 1.7
	 */
	public void sendMessageToAllUsers(String contents) {
	        Set<String> userIds = userMap.keySet();
	        for(String userId: userIds) {
	            this.sendMessageToUser(userId, contents);
	        }
	    }
	
	/**
	 * getUserId:获取用户id
	 * @author zhaoshouyun
	 * @param session
	 * @return
	 * @since JDK 1.7
	 */
	private String  getUserId(WebSocketSession session){
		try {
			String userId = (String)session.getAttributes().get(USER_KEY);
			return userId;
		} catch (Exception e) {
		    e.printStackTrace();
		}
		return null;
	}

}

第三步:编写websocket相关配置,当然可以在xml配置;我现在没有使用xml配置,使用代码配置,需要在xml里添加扫描包<context:component-scan base-package="com.zsy.websocket" />

 /**
 * Project Name:springRabbitMQ
 * File Name:WebSocketConfig.java
 * Package Name:com.zsy.websocket
 * Date:2018年1月31日下午1:10:33
 * Copyright (c) 2018, zhaoshouyun All Rights Reserved.
 *
*/
/**
 * Project Name:springRabbitMQ
 * File Name:WebSocketConfig.java
 * Package Name:com.zsy.websocket
 * Date:2018年1月31日下午1:10:33
 * Copyright (c) 2018, zhaoshouyun All Rights Reserved.
 *
 */

package com.zsy.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;

/**
 * ClassName: WebSocketConfig 
 * Function: TODO ADD FUNCTION. 
 * date: 2018年1月31日 下午1:10:33 
 * @author zhaoshouyun
 * @version 
 * @since JDK 1.7
 */
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {

	/**
	 * 注册handle
	 * @see org.springframework.web.socket.config.annotation.WebSocketConfigurer#registerWebSocketHandlers(org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry)
	 */
	@Override
	public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
          registry.addHandler(myHandler(), "/testHandler").addInterceptors(new WebSocketInterceptor());
          registry.addHandler(myHandler(), "/socketJs/testHandler").addInterceptors(new WebSocketInterceptor()).withSockJS();

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

}
第四步:编写websocket适配器

package com.zsy.websocket;

import java.util.Map;

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor;

/**
 * ClassName: WebSocketInterceptor 
 * Function: TODO ADD FUNCTION. 
 * date: 2018年1月31日 上午11:42:34 
 * @author zhaoshouyun
 * @version 
 * @since JDK 1.7
 */
public class WebSocketInterceptor extends HttpSessionHandshakeInterceptor  {
	/**
	 * TODO 简单描述该方法的实现功能(可选).
	 * @see org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor#beforeHandshake(org.springframework.http.server.ServerHttpRequest, org.springframework.http.server.ServerHttpResponse, org.springframework.web.socket.WebSocketHandler, java.util.Map)
	 */
	@Override
	public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
			Map<String, Object> attributes) throws Exception {
		if(request instanceof ServletServerHttpRequest){
			 ServletServerHttpRequest serverHttpRequest = (ServletServerHttpRequest)request;
	         //获取参数
	         String userId = serverHttpRequest .getServletRequest().getParameter("userId");
	        attributes.put(MyMessageHandler.USER_KEY, userId);
		}
		
		return true;
	}
}
第五步对应的js:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript">

var websocket;

// 首先判断是否 支持 WebSocket
 if('WebSocket' in window) {
     websocket = new WebSocket("ws://localhost:8085/springTest/testHandler?userId=zhaoshouyun");
 } else if('MozWebSocket' in window) {
     websocket = new MozWebSocket("ws://localhost:8085/springTest/testHandler?userId=zhaoshouyun");
 } else {
     websocket = new SockJS("http://localhost:8085/springTest/socketJs/testHandler?userId=zhaoshouyun");
 }

 // 打开连接时
 websocket.onopen = function(evnt) {
     console.log("  websocket.onopen  ");
 };

 // 收到消息时
 websocket.onmessage = function(evnt) {
     alert(evnt.data);
 };

 websocket.onerror = function(evnt) {
     console.log("  websocket.onerror  ");
 };

 websocket.onclose = function(evnt) {
     console.log("  websocket.onclose  ");
 };


function say(){
	 //客户端主动发消息
	 websocket.send(document.getElementById('msg').value);
}

</script>
</head>
<body>
<input type="text" value="" id="msg"><button onclick="say()"></button>
</body>
</html>

第六步测试:

package com.zsy.test.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.zsy.websocket.MyMessageHandler;

/**
 * ClassName: TestController 
 * Function: TODO ADD FUNCTION. 
 * date: 2017年12月14日 上午11:11:23 
 * @author zhaoshouyun
 * @version 
 * @since JDK 1.7
 */
@Controller
public class TestController {

	
	
	@Autowired
	MyMessageHandler handler;
		
	@RequestMapping("/get")
	public String  get(){
		return "index";
	}
	
	@ResponseBody
	@RequestMapping("/get1")
	public String  send(String name){
		handler.sendMessageToUser("zhaoshouyun", "服务端发送的内容:"+name);
		return "success";
	}
	
	
}



猜你喜欢

转载自blog.csdn.net/u011410254/article/details/79216642