前言基础
TCP/IP五层模型与OSI七层模型的协议 更多计网相关的知识可以看这篇文章【计算机网络-五层和七层模型】
1.什么是webSocket
WebSocket协议是基于TCP的一种新的网络协议,他是应用层的一个协议,与http协议同级别。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
2.websocket与其他协议的区别
WebSocket和Http的异同点
相同点:
- 建立在TCP之上,通过TCP协议来传输数据。
- 都是可靠性传输协议。
- 都是应用层协议。
不同点:
- WebSocket是HTML5中的协议,支持持久连接,HTTP不支持持久连接。
- HTTP是单向协议,只能由客户端发起,做不到服务器主动向客户端推送信息。
WebSocket和Socket
Socket本身并不是一个协议,它工作在OSI模型会话层,是一个套接字,TCP/IP网络的API,是为了方便大家直接使用更底层协议而存在的一个抽象层。Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。 WebSocket则是一个典型的应用层协议。 总结: 说白了它俩并没有直接关系
WebSocket HTTP和TCP/IP
WebSocket和HTTP一样,都是建立在TCP之上,通过TCP来传输数据
3.使用websocket简单代码实现
常量类:(可要可不要)
public class WebsocketConst {
public static final String MSG_CMD = "cmd";
public static final String MSG_ID = "msgId";
public static final String MSG_TXT = "msgTxt";
public static final String MSG_USER_ID = "userId";
public static final String CMD_CHECK = "heartcheck";
public static final String CMD_USER = "user";
public static final String CMD_TOPIC = "topic";
public static final String CMD_EMAIL = "email";
public static final String CMD_SIGN = "sign";
public static final String NEWS_PUBLISH = "publish";
}
主要业务实现类:
@Component
@ServerEndpoint("/websocket/{userId}")
public class WebSocket {
private static final Logger log = LoggerFactory.getLogger(WebSocket.class);
private Session session;
private String userId;
private static CopyOnWriteArraySet<WebSocket> webSockets = new CopyOnWriteArraySet<>();
private static Map<String, Session> sessionPool = new HashMap<String, Session>();
@OnOpen
public void onOpen(Session session, @PathParam(value = "userId") String userId) {
try {
this.session = session;
this.userId = userId;
webSockets.add(this);
sessionPool.put(userId, session);
log.info("【websocket消息】有新的连接,总数为:" + webSockets.size());
} catch (Exception e) {
log.error(e.getMessage());
}
}
@OnClose
public void onClose() {
try {
webSockets.remove(this);
sessionPool.remove(this.userId);
log.info("【websocket消息】连接断开,总数为:" + webSockets.size());
} catch (Exception e) {
log.error(e.getMessage());
}
}
public void pushMessage(String userId, String message) {
Session session = sessionPool.get(userId);
if (session != null && session.isOpen()) {
try {
log.info("【websocket消息】 单点消息:" + message);
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
public void pushMessage(String[] ids, String message) {
for (String uid:ids) {
if ("".equals(uid)) continue;
Session session = sessionPool.get(uid);
if (session != null && session.isOpen()) {
try {
log.info("【websocket消息】 单点消息:" + message);
session.getAsyncRemote().sendText(message);
} catch (Exception e) {
log.error(e.getMessage());
}
}
}
}
public void pushMessage(String message) {
try {
webSockets.forEach(ws -> ws.session.getAsyncRemote().sendText(message));
} catch (Exception e) {
log.error(e.getMessage());
}
}
@OnMessage
public void onMessage(String message) {
log.debug("【websocket消息】收到客户端消息:" + message);
JSONObject obj = new JSONObject();
obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK);
obj.put(WebsocketConst.MSG_TXT, "心跳响应");
for (WebSocket webSocket : webSockets) {
webSocket.pushMessage(message);
}
}
}
上面的WebSocket 类 ,你可以作为一个service看待,然后根据自己的业务需求调用里面的业务方法, 例如:可以调用里面重载的三个pushMessage方法来实现 服务层向客户端发送消息 pushMessage(String message): 向所有上线的客户端发送消息 pushMessage(String userId, String message): 指定向单个客户端发送消息 pushMessage(String[] ids, String message): 指定向多个客户端发送消息
|