网站底部的在线人数是如何统计的?-WebSocket探究

我的博客地址http://www.autunomy.top/blog
可能大家如果细心点会发现,网站底部有一个统计当前在线人数的功能,但是一般来说,网站会利用当前登陆用户数量来统计当前在线人数,coding网站并没有强制用户登陆,但是为什么也能实时统计在线人数?

WebSocket协议

http协议是一个单工,只能是客户端发起请求,服务端处理后返回给客户端,不能由服务端主动发送消息,所以不能使用http请求来统计在线人数

WebSocket协议是基于TCP的一种新的网络协议。它实现了客户端与服务器全双工通信,学过计算机网络都知道,既然是全双工,就说明了服务器可以主动发送信息给客户端。

全双工:全双工(Full Duplex)是通讯传输的一个术语。. 通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。. 全双工指可以同时(瞬时)进行信号的双向传输(A→B且B→A)。 指A→B的同时B→A,是瞬时同步的。. 单工 就是在只允许甲方向乙方传送信息,而乙方不能向甲方传送 。

coding网站实现的方法是:coding使用的技术是vue,有一个根组件就是app,所以我们在app组件中,创建websocket连接。但是会有一个bug:当用户使用同一个浏览器打开多个coding的页面,就会创建多个连接,如何解决呢?
解决方法:在创建连接的时候,将客户端ip或者随机uuid发送给服务器,作为唯一标识。如果使用到后者,那么就需要在浏览器本地缓存中进行存储,当浏览器又打开一个coding页面的时候,就将之前存储的uuid发送给服务端,这样就能保证同一个浏览器无论打开多少网页只会统计一个连接。

SpringBoot集合WebSocket

首先需要添加依赖

<dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-websocket</artifactId>  
</dependency> 

开启对WebSocket的支持

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

在这里大家可能会遇到一个问题,就是在使用junit单元测试的时候,会爆这个类的错误,但是目前还没有什么好办法,只能是在使用测试类的同时注释掉这段代码,在结束测试之后打开即可,如果大家有好的解决方法可以通过之后的评论中给博主进行解答

编写Service

@Component
@Slf4j
@Service
@ServerEndpoint("/websocket")//这里写的是websocket的url
public class WebSocketService {
    //注意这里的stringRedisTemplate以及setStringRedisTemplate方法是为了注入redis的操作对象,如果项目中不使用redis就可以删掉这段代码,如果使用redis,必须使用这种方式进行注入,因为静态的变量不能使用@Autowired直接注入
    public static StringRedisTemplate stringRedisTemplate;
    @Resource
    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        WebSocketService.stringRedisTemplate = stringRedisTemplate;
    }

    //建立连接之后的执行的方法
    @OnOpen
    public void onOpen(Session session) {
        log.info("有新的客户端上线");
    }
    //连接关闭之后执行的方法
    @OnClose
    public void onClose() {
        log.info("有客户端离线");
    }
    //连接出错的结果
    @OnError
    public void onError(Throwable throwable) {
        throwable.printStackTrace();
    }
    //客户端给服务器发送消息执行的方法
    @OnMessage
    public void onMessage(String message) {
        log.info("收到客户端发来的消息: {}", message);
    }
    //给客户端发送消息的方法 这里的WebSocketMessage是自定的类
    private void sendTo(WebSocketMessage message) {
    }
}

WebSocketMessage类

//websocket消息类 这里的注解是lombok注解
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class WebSocketMessage {
    private String userId;
    private String message;
}

Vue使用WebSocket

let socket = null;
onMounted(() => {
    socket = new WebSocket(socketUrl);
    //建立连接
    socket.onopen = () => {
        socket.send("建立连接")
    }
    //发送消息
    socket.send("你好")
    //接收消息
    socket.onmessage = () => {
    
    }
    //断开连接执行的方法
    socket.onclose = () => {
        console.log("断开连接!");
    }
})
onUnmounted(() => {
    socket.close();
})

WebSocket的应用其实很广泛,其实qq之类的聊天软件也使用到了WebSocket协议,并不是很难,大家其实自己动手敲一遍代码基本就会使用了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值