Sử dụng java tạo websocket để tạo ứng dụng Chat
Bài đăng này đã không được cập nhật trong 6 năm
Trong bài viết này mình sử dụng websocket trong java để tạo ứng dụng chat, trong bài viết này tôi sẽ hướng dẫn cách tạo máy chủ/máy khách(mở, đóng session, gửi/nhận message....) . Cách gửi tin mã hoá/giải mã
Các thư viện sử dụng
java lib
server lib
org.glassfish.tyrus Bên cạnh sử dụng lib trên bạn có thể sử dụng tomcat, jetty... Nào giờ bắt đầu...
Data model
Dữ liệu tin nhắn
package io.github.ngocitbk.websocket.model;
import lombok.Data;
import java.util.Date;
@Data
public class Message {
private String content;
private String sender;
private Date received;
}
Decoder
Messages sẽ được mã hoá/giải mã bằng JSON format truyền giữa client và server
package io.github.ngocitbk.websocket.model;
import javax.json.Json;
import javax.json.JsonObject;
import javax.websocket.DecodeException;
import javax.websocket.Decoder;
import javax.websocket.EndpointConfig;
import java.io.StringReader;
import java.util.Date;
public class MessageDecoder implements Decoder.Text<Message> {
@Override
public void init(final EndpointConfig config) {
}
@Override
public void destroy() {
}
@Override
public Message decode(final String textMessage) throws DecodeException {
Message message = new Message();
JsonObject jsonObject = Json.createReader(new StringReader(textMessage)).readObject();
message.setContent(jsonObject.getString("message"));
message.setSender(jsonObject.getString("sender"));
message.setReceived(new Date());
return message;
}
@Override
public boolean willDecode(final String s) {
return true;
}
}
Encoder
package io.github.ngocitbk.websocket.model;
import io.github.ngocitbk.websocket.util.JsonUtil;
import javax.websocket.EncodeException;
import javax.websocket.Encoder;
import javax.websocket.EndpointConfig;
public class MessageEncoder implements Encoder.Text<Message> {
@Override
public void init(final EndpointConfig config) {
}
@Override
public void destroy() {
}
@Override
public String encode(final Message message) throws EncodeException {
return JsonUtil.formatMessage(message.getContent(), message.getSender());
}
}
MessageEncoder dùng thư viện json của java để thực hiện, trên là mô hình dữ liệu được truyền giữa server và client
Server side
@javax.websocket.server.ServerEndpoint(value = "/chat", encoders = MessageEncoder.class, decoders = MessageDecoder.class)
public class ServerEndpoint {
static Set<Session> peers = Collections.synchronizedSet(new HashSet<Session>());
@OnOpen
public void onOpen(Session session) {
System.out.println(format("%s joined the chat room.", session.getId()));
peers.add(session);
}
@OnMessage
public void onMessage(Message message, Session session) throws IOException, EncodeException {
String user = (String) session.getUserProperties().get("user");
if (user == null) {
session.getUserProperties().put("user", message.getSender());
}
if ("quit".equalsIgnoreCase(message.getContent())) {
session.close();
}
System.out.println(format("[%s:%s] %s", session.getId(), message.getReceived(), message.getContent()));
//broadcast the message
for (Session peer : peers) {
if (!session.getId().equals(peer.getId())) { // do not resend the message to its sender
peer.getBasicRemote().sendObject(message);
}
}
}
@OnClose
public void onClose(Session session) throws IOException, EncodeException {
System.out.println(format("%s left the chat room.", session.getId()));
peers.remove(session);
//notify peers about leaving the chat room
for (Session peer : peers) {
Message chatMessage = new Message();
chatMessage.setSender("Server");
chatMessage.setContent(format("%s left the chat room.", (String) session.getUserProperties().get("user")));
chatMessage.setReceived(new Date());
peer.getBasicRemote().sendObject(chatMessage);
}
}
}
Client sẽ mở connection đến server và sẽ tạo ra 1 session nối giữa server và client, toàn bộ thông tin message trao đổi giữa client <-> server đều được thực hiện mã hoá và giải mã ở hàm onMesssage Bạn định nghĩa endpoint(url) ở đây @javax.websocket.server.ServerEndpoint
Client side
@javax.websocket.ClientEndpoint(encoders = MessageEncoder.class, decoders = MessageDecoder.class)
public class ClientEndpoint {
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat();
@OnOpen
public void onOpen(Session session) {
System.out.println(format("Connection established. session id: %s", session.getId()));
}
@OnMessage
public void onMessage(Message message) {
System.out.println(format("[%s:%s] %s", simpleDateFormat.format(message.getReceived()), message.getSender(), message.getContent()));
}
}
Client sẽ open connection và send/received message với server
How to run
Start server thôi
public class Server {
public static void main(String[] args) {
org.glassfish.tyrus.server.Server server = new org.glassfish.tyrus.server.Server("localhost", 8887, "/ws", ServerEndpoint.class);
try {
server.start();
System.out.println("Press any key to stop the server..");
new Scanner(System.in).nextLine();
} catch (DeploymentException e) {
throw new RuntimeException(e);
} finally {
server.stop();
}
}
}
Trên mình sẽ start server ở port 8887, tất cả client sẽ đi qua port đó, ở phía server mình có thể đăng ký được nhiều ServerEndpoint (hình như ko giới hạn )
Start client để check giao tiếp client <->server
public static final String SERVER = "ws://localhost:8887/ws/chat";
public static void main(String[] args) throws Exception {
ClientManager client = ClientManager.createClient();
String message;
// connect to server
Scanner scanner = new Scanner(System.in);
System.out.println("Welcome to Tiny Chat!");
System.out.println("What's your name?");
String user = scanner.nextLine();
Session session = client.connectToServer(ClientEndpoint.class, new URI(SERVER));
System.out.println("You are logged in as: " + user);
// repeatedly read a message and send it to the server (until quit)
do {
message = scanner.nextLine();
session.getBasicRemote().sendText(formatMessage(message, user));
} while (!message.equalsIgnoreCase("quit"));
}
Clinet connect server thông qua SERVER = "ws://localhost:8887/ws/chat", đây là 1 dạng địa chỉ websocket.
Chạy ra client giao tiếp với nhau:
Trong bài viết này bạn thấy việc sử dụng java để tạo websocket chát rất đơn giản, bạn có thể dùng nhiều thứ để tạo ví dụ như nodejs...
Source code: https://github.com/ngodinhngoc/websocket
All rights reserved