JAVA使用WebSocket实时显示在线人数

JAVA使用WebSocket实时显示在线人数

有时候我们需要在内容详情页实时浏览人数,这时候我们可以使用websocket实现这个功能。

pom.xml

<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>8.0</version>
    <scope>provided</scope>
</dependency>

或者jar包

tomcat7-websocket.jar

websocket-api.jar

配置类

WebSocketConfig.java

package com.config;
 
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerEndpointConfig;
import java.util.Set;
 
public class WebSocketConfig implements ServerApplicationConfig {
    @Override
    public Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> endpointClasses) {
        return null;
    }
 
    @Override
    public Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> scanned) {
 
        //在这里会把含有@ServerEndpoint注解的类扫描加载进来 ,可以在这里做过滤等操作
 
        return scanned;
    }
}

操作类
ContentWebSocket.java

package com.websocket;
 
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.*;
 
/**
 * @author 。
 */
@ServerEndpoint(value = "/content_websocket")
public class ContentWebSocket {
 
 
    /**
     * 内容集合
     */
    public static Map contentMap=new HashMap<>();
 
 
    /**
     * 创建
     * @param session
     */
    @OnOpen
    public void onOpen(Session session) {
 
    }
 
    /**
     * 发送消息
     * @param contentId
     * @throws IOException
     */
    @OnMessage
    public void sendMessage(Session session,String contentId)  {
        List c = (List) contentMap.get(contentId);
        if (c==null){
            c=new ArrayList();
        }
        c.add(session);
        //创建时把当前会话放在集合中,这样集合大小就是实时浏览人数
        contentMap.put(contentId,c);
        broadcast(c,c.size()+"");
    }
 
    /**
     * 关闭
     */
    @OnClose
    public void onClose(Session session) {
        Map<String, List<String>> requestParameterMap = session.getRequestParameterMap();
        //关闭时从链接获取content的ID
        List<String> contentids = requestParameterMap.get("content_id");
        if (contentids!=null&&contentids.size()>0){
            String contentId=contentids.get(0);
            List c = (List) contentMap.get(contentId);
            if (c!=null){
                //从集合中移除该会话
                c.remove(session);
                contentMap.put(contentId,c);
                broadcast(c,c.size()+"");
            }
 
        }
    }
 
    /**
     * 发生错误
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误");
        error.printStackTrace();
    }
 
 
    /**
     * 消息广播
     * @param sessions
     * @param msg
     */
    public void  broadcast(List<Session> sessions,String msg){
        for (Iterator it=sessions.iterator();it.hasNext();){
            Session session= (Session) it.next();
            try {
                if (session.isOpen()){
                    //当当前会话没有被关闭 发送消息
                    session.getBasicRemote().sendText(msg);
                }else {
                    it.remove();
                }
            } catch (IOException e) {
                e.printStackTrace();
                it.remove();
            }
        }
 
    }
}

页面代码

content.html

<span id="viewing">0</span>人正在看
 
<script>
 
    //观看人数统计
    var ws;
    var  target="ws:localhost:8080/content_websocket?content_id=内容ID";
 
    $(function () {
 
        //处理浏览器兼容性
        if ('WebSocket' in window) {
            ws = new WebSocket(target);
        } else if ('MozWebSocket' in window) {
            ws = new MozWebSocket(target);
        } else {
            alert('WebSocket is not supported by this browser.');
            return;
        }
 
        ws.onopen = function () {
            ws.send('${content.id}')
        };
        ws.onmessage = function (event) {
           $("#viewing").html(event.data);
        };
 
        ws.onclose=function (event) {
 
        }
 
    })
</script>

目前国内知名的第三方websocket框架GoEasy提供“客户端在线列表”接口能力。开发者可以通过以下两种方式获取当前在线客户端列表:

根据channel获取当前在线客户端列表

goEasy.hereNow({
        channels: ["my_channel", "my_channel2"],
        includeUsers: true, //可选项,是否返回用户列表,默认false
        distinct: true //可选项,相同userId的客户端,列表中只保留一个,默认false
    },function(response) {
        alert("hereNow response: " + response);//json格式的response           
        /**
        response示例:
        {
           "code": 200,
           "content": {
              "channels": {
                 "channel_A": {      //channel
                    "channel": "channel_A",
                    "clientAmount": 2,    //在线客户端数量
                    "userAmount": 2,      //在线用户数量
                    "users": [    //在线用户id列表
                       {"id":"Jack","data":"18 years old"}, //在线用户
                       {"id":"Ted","data":""}                                    
                    ]
                 },
                 "channel_B": {       //channel
                    "channel": "channel_B",
                    "clientAmount": 1,     
                    "userAmount": 1,       
                    "users": [     
                       {"id":"Tom","data":"18 years old"}
                    ]
                 }
              }
           }
        }
        **/
    });

根据userId获取当前在线客户端列表

 goEasy.hereNowByUserIds({
        userIds: ["Jack", "Ted", "Tom"],
        includeUsers: true, //可选项,是否返回用户列表,默认false
        distinct: true //可选项,相同userId的客户端,列表中只保留一个,默认false
    },function(response) {
        alert("hereNowByUserIds response: " + response);//json格式的response           
        /**
        response示例:
        {
            "code":200,
            "content":[
                {"userId":"Ted","userData":""},
                {"userId":"Jack","userData":"18 years old"}
            ]
        }
        **/
    });

原文地址: https://www.cnblogs.com/pxblog/p/12593351.html

Comments are closed.