websocket的使用介绍(百分百可以运行)

版权声明:@渔闻520 https://blog.csdn.net/weixin_41060905/article/details/83188534

废话不说,直接上代码:

项目结构:

 这里包一定要导入清楚!

test.java

package net.jiangyi.util;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * @Author: JiangYi
 * @Date: 2018/10/18 21:06
 * @Description:
 */
//将目前的类定义为一个websocket服务器
    @ServerEndpoint("/go")
public class Test {
        //创建一个线程安全发的set集合
    private static CopyOnWriteArraySet<Test> set = new CopyOnWriteArraySet<Test>();
    //与某一个客户端连接会话,需要通过他来来给客户端来发送数据
    private Session session;
    //连接建立成功成功调用的方法
    @OnOpen
    public void OnOpen(Session session){
        this.session=session;
        set.add(this);
        System.out.println("OnOpen()方法被执行````");
        System.out.println("websocket连接建立成功`````");
    }
    //连接关闭的的方法
    @OnClose
    public  void OnClose(){
        set.remove(this);
        System.out.println("OnClose()方法被执行``");
        System.out.println("websocket 连接已近被关闭");
    }
    //接收消息的方法
    @OnMessage
    public void OnMessage(String msg,Session session){
        System.out.println("已经从客户端接收到消息"+msg);
        //这里每秒发送一条数据
        for(int i=0;i<10;i++){

            try {
                Thread.currentThread().sleep(1000);
                //向所有客户端发送消息
                for(Test t:set){
                    t.sendResponse("这是第"+(i+1)+"条消息```");
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        }
        System.out.println("向所有的客户端发送数据```");

    }
    //出错的方法,注意参数不能错
    @OnError
    public  void OnError(Session session,Throwable error){
        System.out.println("OnError()方法被执行·····");
        System.out.println("websocket出错");
    }
    //发送数据到客户端
    public void sendResponse(String str){
        System.out.println("sendResponse()方法被执行");
        try {
            this.session.getBasicRemote().sendText(str);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }



}

index.jsp

<%--
  Created by IntelliJ IDEA.
  User: lenovo
  Date: 2018/10/18
  Time: 21:02
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<script type="text/javascript" src="jquery-3.3.1.js"></script>

<script type="text/javascript">
    $(function(){
        var websocket = null;

        //判断浏览器是否支持websocket
        if('WebSocket' in window) {
            //如果支持,创建websocket对象,注意url格式
            websocket = new WebSocket('ws://localhost:8080/chart/go');
        }else {
            alert('浏览器版本不支持websocket!');
        }

        //定义连接错误的回调方法
        websocket.onerror = function() {
            alert('websocket连接出错!');
        }

        //定义连接成功的回调方法
        websocket.onopen = function() {
            alert('websocket连接成功!');
        }

        //定义websocket关闭的回调方法
        websocket.onclose = function() {
            alert('websocket已关闭!')
        }

        //当窗口关闭时,主动去关闭websocket连接
        window.onbeforeunload = function() {
            closeWebSocket();
        }

        //接收到消息的回调方法
        websocket.onmessage = function(event) {
            handleMsg(event.data);
        }

        $('#send').click(function() {
            websocket.send($('#input').val());
        });
    });

    //关闭websocket
    function closeWebSocket() {
        websocket.close();
    }

    function handleMsg(msg) {
        $('#msg').append(msg + '\n');
    }
</script>
<body>
<input name="input" id="input" type="text" />&nbsp;
<input name="send" id="send" type="button" value="发送请求" />
<br><hr style="width:50%;" align="left">
<textarea name="msg" id="msg" style="width: 260px;height:190px">

</textarea>
</body>

这里再介绍两个知识:

1.CopyOnWriteArraySet是一个线程安全的set集合。

2. websocket  session发送文本消息有两个方法:getAsyncRemote()和getBasicRemote() 同事推荐使用getAsyncRemote()这个方法,网上找了下解释:就是getAsyncRemote是非阻塞式的,getBasicRemote是阻塞式的,表示不懂。推送消息的过程中遇到了一个bug,CSDN的一位网友正好遇到过这个bug, 于是顺便把getAsyncRemote()和getBasicRemote() 的区别给请教了一下,那位网友是这样解释的:

      getAsyncRemote()和getBasicRemote()确实是异步与同步的区别,大部分情况下,推荐使用getAsyncRemote()。由于getBasicRemote()的同步特性,并且它支持部分消息的发送即sendText(xxx,boolean isLast). isLast的值表示是否一次发送消息中的部分消息,对于如下情况:

           session.getBasicRemote().sendText(message, false);

           session.getBasicRemote().sendBinary(data);

           session.getBasicRemote().sendText(message, true);

            由于同步特性,第二行的消息必须等待第一行的发送完成才能进行,而第一行的剩余部分消息要等第二行发送完才能继续发送,所以在第二行会抛出IllegalStateException异常。如果要使用getBasicRemote()同步发送消息,则避免尽量一次发送全部消息,使用部分消息来发送。

ps:代码运行流程图:

猜你喜欢

转载自blog.csdn.net/weixin_41060905/article/details/83188534
今日推荐