首页 > 编程知识 正文

socketJS,socket

时间:2023-05-05 10:03:29 阅读:226050 作者:4693

关于WebSocket的介绍和相关API,网上有很多文档,感觉下面这个说得比较细:

WebSocket介绍WebSocket APISockJS FallbackWebSocket STOMP

这个是SpringBoot整合 WebSocket的文档,前端用的SocketJS/Stomp。后端用的是Spring所支持SocketJS:springboot websocket 一篇足够了

前端用的Stomp来获取client进行SocketJS的API操作:Stomp Over Websocket文档

我们知道SocketJS对Cookie的兼容性不好,网上有看到可以把Cookie信息放到Header中进行传输及获取,这是相关的整合文档:
Spring+WebSocket+SockJS实现实时聊天

关于为什么不直接用原生的WebSocket而用SocketJS应该不用我多说,就是IE10以下不支持ws协议,为了它的兼容性,需要在不支持websocket浏览器下降级成长轮询的方式。而SocketJS和SocketIO都封装了WebSocket。而SocketIO后端官方是用NodeJS实现的,如果要用Java当服务器端,可以使用基于Netty实现的netty-socketio:githup地址,它官方也提供了相应的demo,提出了namespace/room的概念,比较适合当聊天工具的开发,只是要开启新的端口来监听连接(socketJS就不需要)

补充一下:SocketJS中有个registry.setUserDestinationPrefix("/user");有点不容易被理解,看了源码,在convertAndSendToUser和convertAndSend方法时体现了他们的不同之处

SimpMessagingTemplate.class// convertAndSendToUser方法底层调用的convertAndSend方法,只不过参数添加了config中的destinationPrefix及点对点的接收人super.convertAndSend(this.destinationPrefix + user + destination, payload, headers, postProcessor);

另附上后端调用api时主要的代码及注释:

import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.messaging.handler.annotation.MessageMapping;import org.springframework.messaging.handler.annotation.SendTo;import org.springframework.messaging.simp.SimpMessagingTemplate;import org.springframework.messaging.simp.annotation.SendToUser;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.socket.WebSocketSession;import top.fissile.manager.SocketManager;import javax.servlet.ServletRequest;import javax.servlet.http.HttpServletRequest;import java.security.Principal;import java.util.HashMap;import java.util.Map;/** * demo地址:http://123.56.157.29:3333/html/index.html * @Author duln * @Date 2019/12/27 11:27 * @Version 1.0 */@RestController@Slf4jpublic class TestController { @Autowired private SimpMessagingTemplate template; /** * @Description 接收客户端的消息 * @param principal 这是在拦截器中设置的数据,之前只用token给设置个name值 * @param msg 客户端发送过来的消息(也可以用map接收,前端就需要obj转json) */ // 只和前端的发送参数相关,类似RequestMapping,前端直接clent.send('/sendAllUser',...)就可以 @MessageMapping("/sendAllUser") // 貌似得和@MessageMapping连用才生效,也就限制了一般只能用在controller中 // 区别于@SendToUser,@SendTo是用来服务器给客户端群发的:value就是群发的destination,方法返回值就是群发数据 // 如果返回值为Map,则客户端收到的是application/json格式;如果返回值是String,则收到的是xxx/text格式 // @SendTo同template.convertAndSend(),只是template可用于任何地方 @SendTo("/topic/receiveMsg") public Map<String, Object> sendAllUser(Principal principal, String msg) { Map<String, Object> map = new HashMap<>(); map.put("type", "公开"); map.put("userName", principal.getName()); map.put("message", msg); return map; } /** * 客户端请求获取当前人数信息 */ @MessageMapping("/getCount") public void getCount(Principal principal) { Map<String, Object> map = SocketManager.get(); // 与convertAndSend不同的是:this.destinationPrefix + user // super.convertAndSend(this.destinationPrefix + user + destination, payload, headers, postProcessor); template.convertAndSendToUser(principal.getName(), "/queue/count", map); } /** * 点对点用户聊天 */ @MessageMapping("/sendOneUser") public void sendOneUser(Principal principal, Map<String, String> map) { log.info("map = {}", map); String toName = map.get("userName"); String fromName = principal.getName(); WebSocketSession webSocketSession = SocketManager.get(toName); if (webSocketSession != null) { Map<String, Object> toMap = new HashMap<>(); toMap.put("type", "私聊"); toMap.put("message", map.get("message")); Map<String, Object> fromMap = new HashMap<>(toMap); toMap.put("fromName", fromName); toMap.put("toName", "你"); fromMap.put("fromName", "你"); fromMap.put("toName", toName); template.convertAndSendToUser(toName, "/queue/sendUser", toMap); template.convertAndSendToUser(fromName, "/queue/sendUser", fromMap); } }}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。