客戶端與服務端建立單一雙向連接,客戶發送請求後服務端異步處理並推送回應,客戶端可同時執行其他任務。本教學基於 Java EE 7 容器 GlassFish 4,整合 JSON Processing API (JSR-353)、jQuery 與 Bootstrap。
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<plugin>
<groupId>org.glassfish.embedded</groupId>
<artifactId>maven-embedded-glassfish-plugin</artifactId>
<version>4.0</version>
<configuration>
<port>8080</port>
<contextRoot>hascode</contextRoot>
</configuration>
</plugin>
@ServerEndpoint(value = "/chat/{room}", encoders = ChatMessageEncoder.class, decoders = ChatMessageDecoder.class)
public class ChatEndpoint {
private final Logger log = Logger.getLogger(getClass().getName());
@OnOpen
public void open(Session session, @PathParam("room") String room) {
session.getUserProperties().put("room", room);
}
@OnMessage
public void onMessage(Session session, ChatMessage chatMessage) {
String room = (String) session.getUserProperties().get("room");
for (Session s : session.getOpenSessions()) {
if (s.isOpen() && room.equals(s.getUserProperties().get("room"))) {
s.getBasicRemote().sendObject(chatMessage);
}
}
}
}
@ServerEndpoint 定義 URL 模板,支援 @PathParam 注入public class ChatMessage {
private String message;
private String sender;
private Date received;
// getter/setter
}
// 解碼器:JSON → ChatMessage
public class ChatMessageDecoder implements Decoder.Text {
@Override
public ChatMessage decode(String textMessage) {
JsonObject obj = Json.createReader(new StringReader(textMessage)).readObject();
ChatMessage msg = new ChatMessage();
msg.setMessage(obj.getString("message"));
msg.setSender(obj.getString("sender"));
msg.setReceived(new Date());
return msg;
}
}
// 編碼器:ChatMessage → JSON
public class ChatMessageEncoder implements Encoder.Text {
@Override
public String encode(ChatMessage msg) {
return Json.createObjectBuilder()
.add("message", msg.getMessage())
.add("sender", msg.getSender())
.add("received", msg.getReceived().toString())
.build().toString();
}
}
var wsocket;
var serviceLocation = "ws://0.0.0.0:8080/hascode/chat/";
function connectToChatserver() {
room = $('#chatroom option:selected').val();
wsocket = new WebSocket(serviceLocation + room);
wsocket.onmessage = onMessageReceived;
}
function onMessageReceived(evt) {
var msg = JSON.parse(evt.data);
var $line = $('' + msg.received + ' ' + msg.sender + ' ');
$('#response').append($line);
}
function sendMessage() {
var msg = '{"message":"' + $('#message').val() + '", "sender":"' + $('#nickname').val() + '", "received":""}';
wsocket.send(msg);
$('#message').val('').focus();
}
關鍵 API:new WebSocket(url)、onmessage、send()、close()。
mvn package embedded-glassfish:run
瀏覽器開啟 https://localhost:8080/hascode/ 即可體驗多房間即時聊天。