WebSocket通信协议早在2011年就已经被提出,目前主流浏览器对其都有很好支持。
在WebSocket出现之前,对于客户端和服务器需要反复交互数据的解决方案一般都采用“轮询”和“长链接”,后者本质上也是一种“轮询”,这种模式存在很大的弊端,一个是时效差,一个是浪费带宽,每次都需要客户端主动发起请求,服务端永远都是被动的。WebSocket的提出很好地解决了这些问题。WebSocket也是基于tcp/ip协议之上的应用层协议,它借助http协议建立连接,之后以自己的协议传送数据。由于服务端能主动向客户端发送数据,利用这一点结合消息代理,设计出的数据监控系统,可以大大降低数据交互的成本。
STOMP,Streaming Text Orientated Message Protocol,是流文本定向消息协议,也可以说是简单文本协议。由于其设计简单,很容易开发客户端,因此在多种语言和多种平台上得到广泛应用。其中最流行的STOMP消息代理是Apache ActiveMQ。
个人理解Stomp是基于WebSocket协议的具体实现,是在WebSocket协议之上的封装,提供更简单易用的接口。
ActiveMQ支持多种协议,在tcp协议上支持多种类型的消息,TextMessage、MapMessage、ObjectMessage、BytesMessage、和StreamMessage,但是针对STOMP协议只支持TextMessage。所以建议前后端用JSON对象字符串进行交互,使用JSON.stringify()和JSON.parse()去转换JSON对象。
下面贴一段简单的demo演示一下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>HTML5+websocket+activemq+java</title>
<script type="text/javascript" src="js/stomp.js"></script>
</head>
<body>
<script type="text/javascript">
var url = "ws://192.168.1.104:61614/stomp";
var login = "admin";
var passcode = "admin";
destination = "/topic/firstTopic";
client = Stomp.client(url);
var onconnect = function() {
var headers = {selector: "xiaoxitou = 'kt'"};
client.subscribe(destination, function(message) {
//console.log(message.body);
//alert(message);
var msgjson = JSON.parse(message.body);
//alert(typeof(msgjson));
document.getElementsByName("ID")[0].value = msgjson.id;
document.getElementsByName("temp")[0].value = msgjson.temp;
document.getElementsByName("tempset")[0].value = msgjson.tempset;
document.getElementsByName("time")[0].value = msgjson.time;
},headers);
};
client.connect(login, passcode, onconnect);
</script>
<div align="center">
<table border="" cellspacing="" cellpadding="50">
<tr><h1 align="center">空调温度监测</h1></tr>
<tr><td align="center">ID</td><td><input type="text" id="ID" name="ID"/></td></tr>
<tr><td align="center">当前温度</td><td><input type="text" id="temp" name="temp"/></td></tr>
<tr><td align="center">设定温度</td><td><input type="text" id="tempset" name="tempset"/></td></tr>
<tr><td align="center">时间</td><td><input type="text" id="time" name="time"/></td></tr>
</table>
</div>
</body>
</html>
Java端:
public static void sendMessage_kt(Session session,MessageProducer producer) throws Exception {
DataStruct_kt a = new DataStruct_kt();
a.id=1;
a.temp = (float) Math.random()*40;
a.tempset = (float) Math.random()*40;
DateFormat df = new SimpleDateFormat("yyyy-dd-MM HH:mm:ss");
String time = df.format(new Date());
a.time = time;
//ObjectMessage message = session.createObjectMessage(a);
TextMessage message = session.createTextMessage(
"{"
+ "\"id\":\""+a.id+"\","
+ "\"temp\":\""+a.temp+"\","
+ "\"tempset\":\""+a.tempset+"\","
+ "\"time\":\""+a.time+"\""
+"}");
message.setStringProperty("xiaoxitou","kt");
//发送消息到目的地方
System.out.println("发送消息:" + "ActiveMq 发送的消息");
producer.send(message);
}
Java端代码只演示了消息的发送部分,这里也可以使用JSONObject,它可以直接把java普通对象和JSON对象进行转换,还可以转换成JSON对象字符串。当然需要导入相应的jar包。
执行效果如下图,其中数据会每隔1s进行刷新。