WebSocket:⽤WebSocket实现推送你必须考虑的⼏个问题⽬录:
1.WebSocket简介
2.项⽬背景、硬件环境及客户端⽀持
本项⽬通过WebSocket实现同时在线⽤户量⼏千的推送服务器(可内⽹运⾏)。且可实时查看⽤户在线状态。
服务器:centos 6.5、tomcat 7
客户端:移动端(安卓、IOS)、⽹页端。
websocket和socket服务端第三⽅库 :javax.websocket
3.本⽂研究内容
应⽤的线上环境后各种异常情况处理:
使⽤WebSocket时,依赖TCP keepalive还是做业务层⼼跳
服务器如何感知客户端断开(⽤以查看实时⽤户在线状态)
客户端如何感知服务端异常(⽤以决定客户端何时重连)
4.基于javax.websocket服务端代码(源码后续补充git连接)
WebSocketServer.java
package cn.milo.wsdemo;
import org.apache.log4j.Logger;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
/*
* create : 17-07-21
* auth : milo
*/
@ServerEndpoint("/connect/{userId}")
public class WebSocketServer {
private static Logger log = Logger(WebSocketServer.class);
/*
New Connected
*/
@OnOpen
public void onOpen(@PathParam("userId") String userId ,
Session session){
log.info("[WebSocketServer] Connected : userId = "+ userId);
WebSocketUtils.add(userId , session);
}
/*
Send Message
*/
@OnMessage
public String onMessage(@PathParam("userId") String userId,
String message) {
log.info("[WebSocketServer] Received Message : userId = "+ userId + " , message = " + message);
if (message.equals("&")){
return "&";
}else{
return "Got your message ("+ message +").";
}
}
/*
Errot
*/
@OnError
public void onError(@PathParam("userId") String userId,
Throwable throwable,
Session session) {
log.info("[WebSocketServer] Connection Exception : userId = "+ userId + " , throwable = " + Message()); ve(userId);
}
/*
Close Connection
*/
@OnClose
public void onClose(@PathParam("userId") String userId,
Session session) {
log.info("[WebSocketServer] Close Connection : userId = " + userId);
}
}
WebSocketUtils.java
package cn.milo.wsdemo;
import cn.milo.FileUtils.CreateFile;
import org.apache.log4j.Logger;
import javax.websocket.Session;
import java.util.Map;
import urrent.ConcurrentHashMap;
public class WebSocketUtils {
private static Logger log = Logger(WebSocketUtils.class);
public static Map<String, Session> clients = new ConcurrentHashMap<String, Session>();
/*
Add Session
*/
public static void add(String userId, Session session) {
clients.put(userId,session);
log.info("当前连接数 = " + clients.size());
}
/*
Receive Message
*/
public static void receive(String userId, String message) {
log.info("收到消息 : UserId = " + userId + " , Message = " + message);
log.info("当前连接数 = " + clients.size());
}
/*
Remove Session
*/
public static void remove(String userId) {
log.info("当前连接数 = " + clients.size());
}
/
*
Get Session
*/
public static boolean sendMessage(String userId , String message) {
log.info("当前连接数 = " + clients.size());
(userId) == null){
return false;
}else{
<(userId).getAsyncRemote().sendText(message);
return true;
}
}
}
5.客户端代码
<body>
server地址 : <input id ="serveraddress" type="text" /><br/>
您的⽤户id : <input id ="userId" type="text" /><br/>
<button onclick="initSocket()">连接</button><br/>
=====================================================<br/>
消息 : <input id ="message" type="text" /><br/>
<button onclick="send()">发送</button><br/>
=====================================================<br/>
连接状态 : <button onclick="clearConnectStatu()">清空</button><br/>
<div id="connectStatu"></div><br/>
=====================================================<br/>
收到消息 :<br/>
<div id="receivedMessage"></div><br/>
=====================================================<br/>
⼼跳 :<br/>
<div id="heartdiv"></div><br/>
</body>
<script src="<%=basePath%>/resources/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
var heartflag = false;
var webSocket = null;
var tryTime = 0;
$(function () {
// initSocket();
};
});
/**
* 初始化websocket,建⽴连接
*/
function initSocket() {
var serveraddress = $("#serveraddress").val();
var userId = $("#userId").val();
if (!window.WebSocket) {
$("#connectStatu").append(getNowFormatDate()+" 您的浏览器不⽀持ws<br/>");
return false;
}
webSocket = new WebSocket(serveraddress+"/"+userId);
// 收到服务端消息
if(msg.data == "&"){
}else{
$("#receivedMessage").append(getNowFormatDate()+" 收到消息 : "+msg.data+"<br/>");
}
};
// 异常
heartflag = false;
$("#connectStatu").append(getNowFormatDate()+" 异常<br/>");
};
// 建⽴连接
heartflag = true;
heart();
$("#connectStatu").append(getNowFormatDate()+" 建⽴连接成功<br/>");
tryTime = 0;
};
// 断线重连
heartflag = false;
// 重试10次,每次之间间隔10秒
if (tryTime < 10) {
setTimeout(function () {
webSocket = null;
tryTime++;
initSocket();
$("#connectStatu").append( getNowFormatDate()+" 第"+tryTime+"次重连<br/>"); }, 3*1000);
} else {
alert("重连失败.");
}
};
}
function send(){
var message = $("#message").val();
webSocket.send(message);
}
function clearConnectStatu(){
$("#connectStatu").empty();
}
function getNowFormatDate() {
var date = new Date();
var seperator1 = "-";
var seperator2 = ":";
var month = Month() + 1;
var strDate = Date();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
var currentdate = FullYear() + seperator1 + month + seperator1 + strDate
+ " " + Hours() + seperator2 + Minutes()
+ seperator2 + Seconds();
return currentdate;
}
function heart() {
if (heartflag){
webSocket.send("&");
$("#heartdiv").append(getNowFormatDate()+" ⼼跳 <br/>");
}
setTimeout("heart()", 10*60*1000);
}
</script>
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论