Server-Sent Events (SSE)是一種基于HTTP協(xié)議的單向通訊技術(shù)狂秦,只能服務(wù)器向客戶端發(fā)送消息肉拓,如果客戶端需要向服務(wù)器發(fā)送消息葵硕,則需要一個新的 HTTP 請求罐监。SSE的實現(xiàn)方法可能參考阮一鋒老師的文章吴藻。
在Java中,并沒有像HTML5中SSE的封裝實現(xiàn)弓柱,但我們可以模擬一個沟堡,以下為Java與Node.js服務(wù)器后臺通訊的實現(xiàn):
import java.io.*;
import java.net.*;
public class Sse {
public Sse() {
try {
URL url = new URL("http://localhost:3400");
HttpURLConnection urlConnection = (HttpURLConnection)url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setUseCaches(false);
urlConnection.setRequestProperty("Connection", "Keep-Alive");
urlConnection.setRequestProperty("Charset", "UTF-8");
urlConnection.setRequestProperty("Content-Type", "text/plain; charset=UTF-8");
this.output(urlConnection);
InputStream is = new BufferedInputStream(urlConnection.getInputStream());
this.readStream(is);
} catch(Exception e) {
System.out.println("Error:" + e.getMessage());
}
}
public void output(HttpURLConnection conn) {
String data = "HelloNode SSE.";
try {
byte[] dataBytes = data.getBytes();
conn.setRequestProperty("Content-Length", String.valueOf(dataBytes.length));
OutputStream os = conn.getOutputStream();
os.write(dataBytes);
os.flush();
os.close();
} catch(Exception e) {}
}
public void readStream(InputStream is) {
BufferedReader reader = null;
StringBuffer sb = new StringBuffer();
try {
reader = new BufferedReader(new InputStreamReader(is));
String line = "";
while((line = reader.readLine()) != null) {
this.parseMessage(line);
}
reader.close();
} catch(Exception e) {
System.out.println("Error:" + e.getMessage());
}
}
public void parseMessage(String msg) {
//這里可以寫接收消息后的邏輯
}
public static void main(String[] args) {
new Sse();
}
}
而node.js服務(wù)器端的代碼則如下:
var http = require("http");
var server = http.createServer(function(req, res) {
let chunks = [], len = 0;
req.on("data", chunk => {
chunks.push(chunk);
len += chunk.length;
}).on("end", () => {
let buf = Buffer.concat(chunks, len);
console.log("PostData:", buf.toString());
});
setInterval(function() {
//這里可以根據(jù)用戶請求的操作進(jìn)行數(shù)據(jù)處理及返回
res.write(Date.now() + "\r\n");
}, 3000);
});
server.listen(3400);
以上為簡單實現(xiàn), 其中省略了服務(wù)器端的error捕獲以及數(shù)據(jù)處理及返回的操作, 希望能對正在學(xué)習(xí)相關(guān)技術(shù)的人有一點點用處矢空。