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);
		}
	}



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值