websockt统计在线人数

1:websocket的原理?
websocket支持持久连接,http协议不支持持久连接。websocket是基于http协议的。我在公司项目中有个需求:统计管理员名下的在裁判和选手。
        一开始考虑的是用session进行统计。 但是http是短连接,如果需要进行实时查看在线情况就需要,在客户端定时访问服务端。但是每一次访问都要重新开启一个http协议,这是十分消耗资源的。
        websocket是可以持长连接的,每个用户登录成功后,将用户信息放于redis的list中, 随后使用llen命令将数据使用websock的onmessage就可以将数据推送给管理员。
2:怎么测试连接成功?
前端代码:

function  startWebSocket() {
    var websocket= new WebSocket("ws://localhost:8080/test/websocket");
		    websocket.onopen = function (event) {
		//    	websocket.send("前端数据")
		    	  console.log(event)
		    };
		    
		    websocket.onmessage = function(event){
		        setMessageInnerHTML(event.data);
		    }	 
}

后台代码:

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

import javax.servlet.http.HttpSession;
import javax.websocket.EncodeException;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;


@ServerEndpoint(value = "/test/websocket", configurator = GetHttpSessionConfigurator.class, encoders = { DataEncoder.class })
public class WebSocket {

	public static Map<Long, Set<IndexWebSocket>> userSocket = new ConcurrentHashMap<>();
	
	private Session session;
	private Long userId;
	@OnOpen
	public void onOpen(Session session, EndpointConfig config) throws IOException{
		HttpSession httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
		Long userId = (Long) httpSession.getAttribute("userId");
		
		this.session = session;
		this.userId = userId;
		
		if (userSocket.containsKey(this.userId)) {
			userSocket.get(this.userId).add(this);
		} else {
			Set<IndexWebSocket> socketSet = new HashSet<>();
			socketSet.add(this);
			userSocket.put(this.userId, socketSet);
		}
		OnlineUserUtil.push(userId);			
	}
	
	@OnClose
	public void onClose() {
		if (userSocket.get(this.userId).size() == 1) {
			userSocket.remove(this.userId);
		} else {
			userSocket.get(this.userId).remove(this);
		}
	}
	
	@OnMessage
	public void onMessage(String message, Session session) {
	<b>message为接收的前端数据</b>
	//在这可以根据接受的数据进行相应的数据处理
		Map<String, Object> resMap = new HashMap<>();
		resMap.put("msg", "服务器收到你的消息:" + message);
		sendMessageToUser(this.userId, resMap);
	}
	
	@OnError
	public void onError(Session session, Throwable error){
		error.printStackTrace();
	}
	
	public static Boolean sendMessageToUser(Long userId, Object message) {
		if (userSocket.containsKey(userId)) {
			for (IndexWebSocket socket : userSocket.get(userId)) {
				try {
					socket.session.getBasicRemote().sendObject(message);
				} catch (IOException e) {
					e.printStackTrace();
					return false;
				} catch (EncodeException e) {
					e.printStackTrace();
					return false;
				}
			}
			return true;
		}
		return false;
	}
	
	public static void sendMessageToAllUser(Object message) {
		for (Long userId: userSocket.keySet()) {
			sendMessageToUser(userId, message);
		}
	}
	
	public Boolean send(Object message) {
		try {
			this.session.getBasicRemote().sendObject(message);
		} catch (IOException e) {
			e.printStackTrace();
			return false;
		} catch (EncodeException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
}



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

public class OnlineUserUtil {

	public static void add(Long userId, String sessionId) {
			JedisUtil.lpush(Constants.MAT_ONLINE_USER_INFO_MAP + roleName.getValue() + userId , sessionId);
			push(userId);
	}
	

	
	public static void push(Long userId) {
		String pKey ="redis的角色key1";
		String rKey ="redis的角色key2" ;
		
		Long pCount = JedisUtil.llen(pKey );
		JedisUtil.expire(userId, 30 * 60);
		Long rCount = JedisUtil.llen(rKey);
		JedisUtil.expire(userId, 30 * 60);
		Map<String, Object> socketParams = new HashMap<>();
		socketParams.put("playerCount", pCount == null ? 0 : pCount);
		socketParams.put("refereeCount", rCount == null ? 0 : rCount);
		WebSocket.sendMessageToUser(userId, socketParams);
	}
}

3:怎么进行交互数据?
后台给前端传输数据: 由于每个用户登录后,都会调用push方法,这时客户端会立即接收到后台返回的数据。
前端给服务端传输数据:js中 调用用websocket.send(“传输的数据”),后台WebSocket中的onmessage方法内可以进行,并且其中可以根据数据类型进行不同的数据梳理。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值