主题 : 基于WebSocket的实时聊天*码
级别: 童生
UID: 113563
积分:10 加为好友
威望: 0 精华: 0
主题:10 回复:1
注册时间:2017-05-24
在线时长:0
1#   发表于:2017-05-31 14:14:29  IP:119.17.*.*
下面是上课了的讲师用过的一段通过代码示例来展示基于WebSocket的实时聊天
1.服务器端实现
package t8j8.examples;
 
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
 
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
 
@ServerEndpoint(value = "/ws/chat/{nickName}")
public class Chat {
 
    /**
     * 连接对象集合
     */
    private static final Set<Chat> connections = new CopyOnWriteArraySet<Chat>();
 
    private String nickName;
 
    /**
     * WebSocket Session
     */
    private Session session;
 
    public Chat() {
    }
 
    /**
     * 打开连接
     * 
     * @param session
     * @param nickName
     */
    @OnOpen
    public void onOpen(Session session,
            @PathParam(value = "nickName") String nickName) {
 
        this.session = session;
        this.nickName = nickName;
 
        connections.add(this);
        String message = String.format("System> %s %s", this.nickName,
                " has joined.");
        Chat.broadCast(message);
    }
 
    /**
     * 关闭连接
     */
    @OnClose
    public void onClose() {
        connections.remove(this);
        String message = String.format("System> %s, %s", this.nickName,
                " has disconnection.");
        Chat.broadCast(message);
    }
 
    /**
     * 接收信息
     * 
     * @param message
     * @param nickName
     */
    @OnMessage
    public void onMessage(String message,
            @PathParam(value = "nickName") String nickName) {
        Chat.broadCast(nickName + ">" + message);
    }
 
    /**
     * 错误信息响应
     * 
     * @param throwable
     */
    @OnError
    public void onError(Throwable throwable) {
        System.out.println(throwable.getMessage());
    }
 
    /**
     * 发送或广播信息
     * 
     * @param message
     */
    private static void broadCast(String message) {
        for (Chat chat : connections) {
            try {
                synchronized (chat) {
                    chat.session.getBasicRemote().sendText(message);
                }
            } catch (IOException e) {
                connections.remove(chat);
                try {
                    chat.session.close();
                } catch (IOException e1) {
                }
                Chat.broadCast(String.format("System> %s %s", chat.nickName,
                        " has bean disconnection."));
            }
        }
    }
}
   说明: 
    代码中ServerEndpoint注解的value值中有个nickName的参数占位符,该参数占位符称为路径参数,路径参数可以通过方法参数注解(@PathParam)进行设置并且获取;
    在Endpoint注解的类中OnClose,OnOpen,OnError注解的方法只有一个,OnMessage注解的方法可以有多个这个容易理解因为WebSocket可能处理的信息有text,binary,textStream等。
2.客户端实现
  如果使用Maven的话,可以添加java_websocket jar的依赖。
<dependency>
            <groupId>org.java-websocket</groupId>
            <artifactId>Java-WebSocket</artifactId>
            <version>1.3.0</version>
            <scope>runtime</scope>
        </dependency>
如果开发Web客户端则可以选择支持WebSocket的浏览器,使用HTML5技术。

下面是使用java_websocket来实现客户端的代码:
package t8j8.examples.client;
 
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Scanner;
 
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.drafts.Draft_17;
import org.java_websocket.handshake.ServerHandshake;
 
public class TestTocatWebSocket {
 
    public static void main(String[] args) throws URISyntaxException {
 
        String url = "ws://localhost:8080/t8j8/ws/chat/" + args[0];
        WebSocketClient wc = new WebSocketClient(new URI(url), new Draft_17()) {
 
            @Override
            public void onOpen(ServerHandshake handshakedata) {
                System.out.println(handshakedata.getHttpStatusMessage());
            }
 
            @Override
            public void onMessage(String message) {
                System.out.println(message);
            }
 
            @Override
            public void onError(Exception ex) {
            }
 
            @Override
            public void onClose(int code, String reason, boolean remote) {
            }
        };
 
        wc.connect();
 
        while (true) {
            Scanner scanner = new Scanner(System.in);
            String message = scanner.nextLine();
            if (message.equals("q")) {
                wc.close();
                break;
            }
            scanner.close();
            wc.send(message);
        }
    }
}
 说明:
    客户端中要说明的是new Draft_17()对象的创建,通过类名可以得知草案的意思。由于Websocket标准迟迟没有发布,因而之前实现都是依据草案进行,而这里的Draft_17对应的WebSocket版本正是:【"Sec-WebSocket-Version", "13"  】可惜,java_websocket包迟迟没有更新内容,名称出现误解人的地方。
级别: 解元
UID: 110327
积分:363 加为好友
威望: 0 精华: 0
主题:0 回复:295
注册时间:2017-02-07
在线时长:0
2#   发表于:2017-05-31 14:53:07  IP:125.83.*.*
过来学习一下
FreeCMS java开源CMS
1 共1页