Java Web应用之Websocket

1. 介绍

webSocket是HTML5新增的协议,是一个持久化的协议。它的目的是在浏览器和服务器之间建立一个不受限的双向通信通道。例如:服务器可以在任意时刻向浏览器发送消息。

webSocket的出现,让浏览器和服务器之间可以建立无限制的全双工通信,任何一方都可以主动发消息给对方。wesocket并不是全新的协议,而是利用HTTP协议来建立连接的。

  • WebSocket通过HTTP端口80和443进行工作,并支持HTTP代理和中介,从而使其与HTTP协议兼容。
  • 为了实现兼容性,WebSocket握手使用HTTP Upgrade头从HTTP协议更改为WebSocket协议。
  • Websocket使用ws或wss的统一资源标志符(URI),分别对应明文和加密连接。

2. 实现方式

1)编程式:继承类javax.websocket.Endpoint并实现其方法

2)注解式:定义一个类,在类上添加@ServerEndpoint注解,表明该类是一个webSocket类。

@ServerEndpoint可以注解到任何类上,但是想实现服务端的完整功能,还需要配合几个生命周期的注解使用,这些生命周期注解只能注解在方法上:

@OnOpen 建立连接时触发。

@OnClose 关闭连接时触发。

@OnError 发生异常时触发。

@OnMessage 接收到消息时触发。

3. 注解方式实现聊天的事例

1. 引用maven

<dependency>
  <groupId>javax.websocket</groupId>
  <artifactId>javax.websocket-api</artifactId>
  <version>1.1</version>
  <scope>provided</scope>
</dependency>

2. 服务器端代码实现

@ServerEndpoint(value = "/myWebSocket/{userId}")
public class MyWebSocket{
    private static Map<String, MyWebSocket> map = new HashMap<>();
    private Session session;
    private String userId;
    @OnOpen
    public void onOpen(Session session,  @PathParam(value="userId") String userId) {
        this.session = session;
        this.userId = userId;
        map.put(userId, this);
        System.out.println(userId+"登录了");
    }

    @OnClose
    public void onClose(){
        System.out.println("onclose");
        map.remove(userId);
    }

    @OnError
    public void onError(Throwable t) throws IOException {
        System.out.println("onerror");
        this.session.close(new CloseReason(CloseReason.CloseCodes.CLOSED_ABNORMALLY, "系统异常"));
    }

    @OnMessage
    public void onMessage(String message, Session session){
        System.out.println("收到:"+message);
        for (String s : map.keySet()) {
            map.get(s).sendMessage(message);
        }
    }

    public void sendMessage(String message){
        try {
            this.session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

3. 客户端代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>
        <div>
            姓名:<input type="text" id="userName" />
            <button id="connect" onclick="connectSocket()">连接</button>
            <button id="close" onclick="closeSocket()">断开</button>
        </div>
        <div>
            内容:<input type="text" id="chat" />
            <button id="send" onclick="sendMessage()">发送</button>
        </div>
    </p>

    <div id="console-container">
        <div id="console"/>
    </div>

<script type="application/javascript">
    let socket = null;
    function connectSocket(){
        var a = document.getElementById("userName").value
        connect("ws://localhost:8080/myWebSocket/"+a)
    }
    function closeSocket(){
        if(socket != null){
            socket.close()
            socket = null
        }
    }
    function sendMessage(){
        var name = document.getElementById("userName").value
        var message = document.getElementById("chat").value
        if(socket != null){
            socket.send(name+"说:"+message)
            document.getElementById("chat").value='';
        }
    }
    function connect(host){
        if ('WebSocket' in window) {
            socket = new WebSocket(host);
        } else if ('MozWebSocket' in window) {
            socket = new MozWebSocket(host);
        } else {
            console.log('Error: WebSocket is not supported by this browser.');
            return;
        }
        socket.onopen= function (){
            console.log("Info: websocket connection opend.")
        }
        socket.onclose=function(){
            console.log("Info:websocket connection closed.")
        }
        socket.onmessage = function(message){
            var console = document.getElementById('console');
            var p = document.createElement('p');
            p.innerHTML = message.data;
            console.appendChild(p);
            while (console.childNodes.length > 25) {
                console.removeChild(console.firstChild);
            }
            console.scrollTop = console.scrollHeight;
        }
    }
</script>
</body>
</html>

4. 打开两个页面,分别以小王和小李身份建立连接,然后发送内容,就可以互相聊天了。

 

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值