美文网首页JAVA环境搭建
史上最全Websocket通信测试

史上最全Websocket通信测试

作者: 宇宙小神特别萌 | 来源:发表于2019-04-17 14:29 被阅读1126次

    H5和H5之间通信

    H5和Andorid之间通信

    Andorid和Andorid之间通信

    H5通过http协议调用接口发送消息-给移动Andorid、H5等

    后台支持语言:java

    前端支持语言:Andorid(java)、H5(html)、jsp等

    发送:发送给所有连接者、发送给所有在线者、发送给指定用户、及(发送对象)用户不在线处理

    注:把连接地址改了,可以直接使用复制代码测试使用;

    H5和Andorid测试页面:

    Andorid测试页面 --消息发送者 发送指定用户 【消息接收者1】,也可以发送所有人
    Andorid测试页面.jpg
    消息接收者1 消息接收者2
    测试页面1.jpg 测试页面2.jpg
    通过Http发送测试页面
    发送消息给所有在线用户 发送消息给指定在线用户 --【测试用户 -张三】
    http测试发送消息给所有在线用户.jpg http测试发送消息给指定在线用户.jpg
    测试用户李四 测试用户张三
    测试用户【李四】.jpg 测试用户【张三】.jpg

    java后台代码

    引入依赖:
    <!--集成移动和H5的java_websocket-->
            <dependency>
                <groupId>org.java-websocket</groupId>
                <artifactId>Java-WebSocket</artifactId>
                <version>1.3.0</version>
            </dependency>
    

    springboot项目结构,也可用spring项目,和框架没有关系,没有影响

    代码类路径.png

    1.WebSocketPool自定义工具类

    主要是连接池,存用户和WebSocket连接

    自定义 WebSocketPool.java

    package com.dist.utils;
    
    import org.java_websocket.WebSocket;
    
    import java.util.*;
    
    public class WebSocketPool {
        //连接-用户名
        private static final Map<WebSocket, String> userconnections = new HashMap<WebSocket, String>();
          
        /** 
         * 获取用户名 
         * @param conn 
         * @return 
         */  
        public static String getUserByKey(WebSocket conn) {  
            return userconnections.get(conn);  
        }  
      
        /** 
         * 获取在线总数 
         * @return 
         */  
        public static int getUserCount() {  
            return userconnections.size();  
        }  
      
        /** 
         * 获取WebSocket 
         * @param user 
         * @return 
         */  
        public static WebSocket getWebSocketByUser(String user) {  
            Set<WebSocket> keySet = userconnections.keySet();
            synchronized (keySet) {  
                for (WebSocket conn : keySet) {  
                    String cuser = userconnections.get(conn);  
                    if (cuser.equals(user)) {  
                        return conn;  
                    }  
                }  
            }  
            return null;  
        }  
      
        /** 
         * 向连接池中添加连接 
         * @param user 
         * @param conn 
         */  
        public static void addUser(String user, WebSocket conn) {  
            userconnections.put(conn, user); // 添加连接  
        }
    
        /**
         * 获取所有连接池
         */
        public static Set<WebSocket> getAllWebSocket() {
                return userconnections.keySet();
        }
    
        /**
         * 移除连接池中的连接
         * @param conn
         * @return
         */
        public static boolean removeUser(WebSocket conn) {
            if (userconnections.containsKey(conn)) {
                userconnections.remove(conn); // 移除连接
                return true;
            } else
                return false;
        }
      
        /** 
         * 获取所有的在线用户 
         * @return 
         */  
        public static Collection<String> getOnlineUser() {
            List<String> setUsers = new ArrayList<String>();
            Collection<String> setUser = userconnections.values();  
            for (String u: setUser) {  
                setUsers.add(u);  
            }  
            return setUsers;  
        }
      
        /** 
         * 向特定的用户发送数据 
         * @param conn 
         * @param message 
         */  
        public static void sendMessageToOnlineUser(WebSocket conn, String message) {
            if (null != conn) {  
                conn.send(message);  
            }  
        }
    
        /**
         * 向所有在线用户发送消息
         * @param message
         */
        public static void sendMessageToOnlineAllUser(String message) {
            Set<WebSocket> keySet = userconnections.keySet();  
            synchronized (keySet) {
                for (WebSocket conn : keySet) {  
                    String user = userconnections.get(conn);  
                    if (user != null) { conn.send(message);  
                    }  
                }  
            }  
        }  
    }
    

    2.创建房间类

    为的是开启房间

    ChatServer.java

    package com.dist.service;
    
    import com.dist.utils.WebSocketPool;
    import org.java_websocket.WebSocket;
    import org.java_websocket.handshake.ClientHandshake;
    import org.java_websocket.server.WebSocketServer;
    
    import java.io.IOException;
    import java.net.InetSocketAddress;
    import java.net.UnknownHostException;
    import java.util.Collection;
    import java.util.Set;
    
    /**
     * 与不同的客户端进行通讯的思路为:
     * Step1:在连接成功的时候,向服务器发送自己的用户名,服务器做用户标记;
     * Step2: 发送消息,格式为“XX@XXX”,@前面表示将要发送的对象,“all”表示群发,@后面表示发送的消息。
     */
    public class ChatServer extends WebSocketServer {
    
        private String username;
    
        public ChatServer(int port) throws UnknownHostException {
            super(new InetSocketAddress(port));
        }
    
        public ChatServer(InetSocketAddress address) {
            super(address);
            System.out.println("地址:"+address);
        }
    
        @Override
        public void onOpen(WebSocket conn, ClientHandshake handshake) {
    
            System.out.println("连接:"+conn);
    
            sendToAll(conn.getRemoteSocketAddress().getAddress().getHostAddress()
                    + " 进入房间 !");
    
            System.out.println(conn.getRemoteSocketAddress().getAddress()
                    .getHostAddress()
                    + " 进入房间 !");
        }
    
        @Override
        public void onClose(WebSocket conn, int code, String reason, boolean remote) {
    
            sendToAll(conn.getRemoteSocketAddress().getAddress().getHostAddress()
                    + " 离开房间 !");
    
            System.out.println(conn.getRemoteSocketAddress().getAddress()
                    .getHostAddress()
                    + " 离开房间 !");
    
            //触发关闭事件
            userLeave(conn);
        }
    
        //消息发送
        @Override
        public void onMessage(WebSocket conn, String message) {
    
            //判断是否是第一次接收的消息
            boolean isfirst = true;
    
            /*sendToAll("["
                    + conn.getRemoteSocketAddress().getAddress().getHostAddress()
                    + "]" + message);*/
    
            System.out.println("["
                    + conn.getRemoteSocketAddress().getAddress().getHostAddress()
                    + "]" + message);
    
            //判断是否已在连接池中
            Set<WebSocket> webSockets=WebSocketPool.getAllWebSocket();
            for (WebSocket webSocket : webSockets){
                if (webSocket.equals(conn)){
                    isfirst =false;
                }
            }
    
            if (isfirst) {
                this.username = message;
                //客户端发送消息到服务器是触发事件
                if (message != null){
                    //判断用户是否已经在线
                    WebSocket webSocketByUser = WebSocketPool.getWebSocketByUser(message);
                    if (null == webSocketByUser){
                        //将用户加入连接池-在线
                        this.userJoin(username, conn);
                        System.out.println("用户" + username + "上线,在线人数:" + WebSocketPool.getUserCount());
                    }else {
                        WebSocketPool.sendMessageToOnlineUser(conn,"["+username+"] 用户已在线,请您换个用户登录!");
                    }
                }
            } else {
                String[] msg = message.split("@", 2);//以@为分隔符把字符串分为xxx和xxxxx两部分,msg[0]表示发送至的用户名,all则表示发给所有人
                if (msg[0].equals("all")) {
                    sendToAll(msg[1]);
                } else {
                    //指定用户发送消息
                    sendMessageToUser(conn,msg[0], msg[1]);
                }
            }
        }
    
        //异常抛出
        @Override
        public void onError(WebSocket conn, Exception e) {
            e.printStackTrace();
            if (conn != null) {
                conn.close();
            }
        }
    
        // 发送给所有进入房间的人
        private void sendToAll(String text) {
            Collection<WebSocket> conns = connections();
            synchronized (conns) {
                for (WebSocket client : conns) {
                    client.send(text);
                }
            }
        }
    
        // 测试
        public static void main(String[] args) throws InterruptedException,
                IOException {
            /*int port = 8887;
    
            ChatServer server = new ChatServer(port);
            server.start();
    
            System.out.println("房间已开启,等待客户端接入,端口号: " + server.getPort());
    
            BufferedReader webSocketIn = new BufferedReader(new InputStreamReader(
                    System.in));
    
            while (true) {
                String stringIn = webSocketIn.readLine();
                // 发送给所有的聊天者
                server.sendToAll(stringIn);
            }*/
        }
    
        /**
         * 用户下线处理
         * @param conn
         */
        public void userLeave(org.java_websocket.WebSocket conn) {
            String user = WebSocketPool.getUserByKey(conn);
            boolean b = WebSocketPool.removeUser(conn); // 在连接池中移除连接
            if (b) {
                WebSocketPool.sendMessageToOnlineAllUser(user); // 把当前用户从所有在线用户列表中删除
                String leaveMsg = "[系统]" + user + "下线了";
                WebSocketPool.sendMessageToOnlineAllUser(leaveMsg); // 向在线用户发送当前用户退出的信息
            }
        }
    
        /**
         * 用户上线处理
         * @param user
         * @param conn
         */
        public void userJoin(String user, org.java_websocket.WebSocket conn) {
            WebSocketPool.sendMessageToOnlineAllUser(user); // 把当前用户加入到所有在线用户列表中
            String joinMsg = "[系统]" + user + "上线了!";
            WebSocketPool.sendMessageToOnlineAllUser(joinMsg); // 向所有在线用户推送当前用户上线的消息
            WebSocketPool.addUser(user, conn); // 向连接池添加当前的连接的对象
            WebSocketPool.sendMessageToOnlineUser(conn, WebSocketPool.getOnlineUser().toString());  // 向当前连接发送当前在线用户的列表
    
        }
    
        /**
         * 发送消息给指定用户
         * @param currentConnection 当前连接
         * @param user  发送对象
         * @param message 消息
         */
        public void sendMessageToUser(WebSocket currentConnection,String user,String message){
            WebSocket conn = WebSocketPool.getWebSocketByUser(user);  //获取发送对象用户的在线连接
            if (null != conn){
                //向特定在线用户发送消息
                WebSocketPool.sendMessageToOnlineUser(conn,message);
                //同时发送消息给当前用户
                WebSocketPool.sendMessageToOnlineUser(currentConnection,message);
            }else {
                WebSocketPool.sendMessageToOnlineUser(currentConnection,"["+user+"] 用户不在线,请您稍后发送!");
                System.out.println("["+user+"] 用户不在线,请您稍后发送!");
                WebSocketPool.sendMessageToOnlineUser(currentConnection,"当前在线人数:"+WebSocketPool.getUserCount()+"  有:"+WebSocketPool.getOnlineUser());
            }
        }
    }
    

    3.Http发送消息

    在controller层 创建WebSocketController.java

    package com.dist.controller;
    
    import com.dist.utils.WebSocketPool;
    import org.java_websocket.WebSocket;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * @author zhengja@dist.com.cn
     * @data 2019/4/17 14:54
     */
    @RestController
    @RequestMapping("/WebSocket")
    public class WebSocketController {
    
         //推送给所有在线用户
        @RequestMapping(value = "v1/sendAllUser", method = RequestMethod.GET)
        public void sendAllUser(@RequestParam String message){
            //推送给所有在线用户
            WebSocketPool.sendMessageToOnlineAllUser(message);
        }
      
        //推送给在线的指定用户
        @RequestMapping(value = "v1/sendUser", method = RequestMethod.GET)
        public void loginWithDevice(@RequestParam String pushObject,
                                    @RequestParam String message){
            //推送的设备对象
            List<String> userlist = null;
            if (pushObject == null || "".equals(pushObject)) {
                System.out.println("推送对象不能为nuul");
            } else {
                userlist = new ArrayList<>(Arrays.asList(pushObject.split(",")));
            }
            for (String user : userlist){
                //根据用户查找推送的连接对象是否在线
                WebSocket webSocketByUser = WebSocketPool.getWebSocketByUser(user);
                if (null != webSocketByUser){
                    //推送给在线的指定用户
                    WebSocketPool.sendMessageToOnlineUser(webSocketByUser,message);
                }else {
                    //未推送成功处理模块
                    System.out.println("用户 【"+user+"】 不在线,推送失败 ! ");
                }
            }
        }
    
    }
    
    

    4.创建启动任务

    项目起动后自动启动这个任务-开启房间

    TestStarts.java

    import com.dist.service.ChatServer;
    import org.springframework.beans.factory.InitializingBean;
    import org.springframework.stereotype.Component;
    
    @Component
    public class TestStarts implements InitializingBean {
    
        @Override
        public void afterPropertiesSet() throws Exception {
            int port = 8887;
    
            ChatServer server = new ChatServer(port);
            server.start();
            System.out.println("项目启动中:房间已开启");
            System.out.println("等待客户端接入的端口号: " + server.getPort());
    
        }
    }
    

    H5前端代码:

    H5测试页面:引入jquery.js (放同级目录)


    页面目录.png

    目前测试页面上的数据信息是写死的,自己可以重后台获取数据,写成动态的

    测试页面1

    H5-WebSocket.html

    注意:var wsUri ="ws://129.204.207.127:8887"; 把地址改成自己的服务器地址,端口不是服务器的,是TestStarts.java启动任务自定义创建的

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/html">
    <head>
        <meta charset="UTF-8">
        <title>H5-WebSocket Test</title>
        <script src="jquery.js"></script>
    </head>
    <body>
    
    <br name="#" method="post">
        <!--YOUR DATA AREA-->
        <label id="a">当前用户</label>
        <select id="loginsel">
            <option value="2">李四</option>
            <option value="3">张三</option>
            <option value="4">王二</option>
        </select>
        <input type="button" value="连接" id="btnconnection" onclick="connectionAction()"/>
        <input type="button" value="断开" id="btndisconnect" onclick="disconnectAction()"/></br></br>
        <label id="b">发送对象</label>
        <select id="sel">
            <option value="1" selected>all</option>
            <option value="2">李四</option>
            <option value="3">张三</option>
            <option value="4">王二</option>
        </select>
        <label id="msg">要发送的信息</label><input type="text" id="message">
        <input type="button" id="btnsendMessage" value="发送消息" onclick="sendMessageAction()">
    </form>
    
    <script language="javascript"type="text/javascript">
        var wsUri ="ws://129.204.207.127:8887";
        var output;
        var message;
        var userToMessage;
        var websocket;
    
        function connectionAction() {
            output = document.getElementById("output");
            //websocket的房间
            websocket = new WebSocket(wsUri);
            //打开连接
            websocket.onopen = function(evt) {
                var loginuser = $('#loginsel option:selected').text();
                websocket.send(loginuser);
            };
            websocket.onmessage = function(evt) {
                onMessage(evt)
            };
            websocket.onerror = function(evt) {
                onError(evt)
            };
            $("#loginsel").attr("disabled","disabled");
            $("#btnconnection").attr("disabled","disabled");
    
            $("#btndisconnect").removeAttr("disabled");
            $("#sel").removeAttr("disabled");
            $("#msg").removeAttr("disabled");
            $("#btnsendMessage").removeAttr("disabled");
        }
    
        //给指定用户发送消息
        function sendMessageAction() {
            var sendTouser = $('#sel option:selected').text();
            message =document.getElementById("message").value;
            userToMessage = sendTouser +"@"+message;
            websocket.send(userToMessage);
        }
    
        //断开连接
        function disconnectAction() {
            websocket.close();
            writeToScreen("您已断开连接");
    
            $("#loginsel").removeAttr("disabled");
            $("#btnconnection").removeAttr("disabled");
    
            $("#btndisconnect").attr("disabled","disabled");
            $("#sel").attr("disabled","disabled");
            $("#msg").attr("disabled","disabled");
            $("#btnsendMessage").attr("disabled","disabled");
        }
    
      /*  function init() {
            output = document.getElementById("output");
            testWebSocket();
        }
        function testWebSocket() {
            websocket = new WebSocket(wsUri);
            websocket.onopen = function(evt) {
                onOpen(evt)
            };
            websocket.onmessage = function(evt) {
                onMessage(evt)
            };
            websocket.onerror = function(evt) {
                onError(evt)
            };
            websocket.onclose = function(evt) {
                onClose(evt)
            };
        }*/
    
        function onOpen(evt) {
            writeToScreen("CONNECTED");
            doSend("Zhansna");
        }
    
        function onClose(evt) {
            writeToScreen("您已断开连接");
            websocket.close();
        }
    
        //接收消息
        function onMessage(evt) {
            writeToScreen('<span style="color: blue;">RESPONSE: '+ evt.data+'</span>');
        }
    
        function onError(evt) {
            writeToScreen('<span style="color: red;">ERROR:</span> '+ evt.data);
        }
    
        function doSend(message) {
            writeToScreen("SENT: " + message);
            websocket.send(message);
        }
    
        function writeToScreen(message) {
            var pre = document.createElement("p");
            pre.style.wordWrap = "break-word";
            pre.innerHTML = message;
            output.appendChild(pre);
        }
    
        window.addEventListener("load", init, false);
    </script>
    <h2>WebSocket Test</h2>
    <div id="output"></div>
    </body>
    </html>
    
    测试页面2

    H5-WebSocket2.html

    <!DOCTYPE html>
    <html lang="en" xmlns="http://www.w3.org/1999/html">
    <head>
        <meta charset="UTF-8">
        <title>H5-WebSocket Test2</title>
        <script src="jquery.js"></script>
    </head>
    <body>
    
    <br name="#" method="post">
        <!--YOUR DATA AREA-->
        <label id="a">当前用户</label>
        <select id="loginsel">
            <option value="2">李四</option>
            <option value="3">张三</option>
            <option value="4">王二</option>
        </select>
        <input type="button" value="连接" id="btnconnection" onclick="connectionAction()"/>
        <input type="button" value="断开" id="btndisconnect" onclick="disconnectAction()"/></br></br>
        <label id="b">发送对象</label>
        <select id="sel">
            <option value="1" selected>all</option>
            <option value="2">李四</option>
            <option value="3">张三</option>
            <option value="4">王二</option>
        </select>
        <label id="msg">要发送的信息</label><input type="text" id="message">
        <input type="button" id="btnsendMessage" value="发送消息" onclick="sendMessageAction()">
    </form>
    
    <script language="javascript"type="text/javascript">
        var wsUri ="ws://129.204.207.127:8887";
        var output;
        var message;
        var userToMessage;
        var websocket;
    
        function connectionAction() {
            output = document.getElementById("output");
            //websocket的房间
            websocket = new WebSocket(wsUri);
            //打开连接
            websocket.onopen = function(evt) {
                var loginuser = $('#loginsel option:selected').text();
                websocket.send(loginuser);
            };
            websocket.onmessage = function(evt) {
                onMessage(evt)
            };
            websocket.onerror = function(evt) {
                onError(evt)
            };
            $("#loginsel").attr("disabled","disabled");
            $("#btnconnection").attr("disabled","disabled");
    
            $("#btndisconnect").removeAttr("disabled");
            $("#sel").removeAttr("disabled");
            $("#msg").removeAttr("disabled");
            $("#btnsendMessage").removeAttr("disabled");
        }
    
        //给指定用户发送消息
        function sendMessageAction() {
            var sendTouser = $('#sel option:selected').text();
            message =document.getElementById("message").value;
            userToMessage = sendTouser +"@"+message;
            websocket.send(userToMessage);
        }
    
        //断开连接
        function disconnectAction() {
            websocket.close();
            writeToScreen("您已断开连接");
    
            $("#loginsel").removeAttr("disabled");
            $("#btnconnection").removeAttr("disabled");
    
            $("#btndisconnect").attr("disabled","disabled");
            $("#sel").attr("disabled","disabled");
            $("#msg").attr("disabled","disabled");
            $("#btnsendMessage").attr("disabled","disabled");
        }
    
      /*  function init() {
            output = document.getElementById("output");
            testWebSocket();
        }
        function testWebSocket() {
            websocket = new WebSocket(wsUri);
            websocket.onopen = function(evt) {
                onOpen(evt)
            };
            websocket.onmessage = function(evt) {
                onMessage(evt)
            };
            websocket.onerror = function(evt) {
                onError(evt)
            };
            websocket.onclose = function(evt) {
                onClose(evt)
            };
        }*/
    
        function onOpen(evt) {
            writeToScreen("CONNECTED");
            doSend("Zhansna");
        }
    
        function onClose(evt) {
            writeToScreen("您已断开连接");
            websocket.close();
        }
    
        //接收消息
        function onMessage(evt) {
            writeToScreen('<span style="color: blue;">RESPONSE: '+ evt.data+'</span>');
        }
    
        function onError(evt) {
            writeToScreen('<span style="color: red;">ERROR:</span> '+ evt.data);
        }
    
        function doSend(message) {
            writeToScreen("SENT: " + message);
            websocket.send(message);
        }
    
        function writeToScreen(message) {
            var pre = document.createElement("p");
            pre.style.wordWrap = "break-word";
            pre.innerHTML = message;
            output.appendChild(pre);
        }
    
        window.addEventListener("load", init, false);
    </script>
    <h2>WebSocket Test2</h2>
    <div id="output"></div>
    </body>
    </html>
    

    现在就可以实现H5页面之间的通信啦
    以上只是H5测试用例,真正用的项目中也是这样,只不过,要根据项目需求该代码逻辑。我的项目就是版本推送和反馈消息的及时推送;

    Andorid测试代码:

    测试最好创建空白的Andorid app

    在.gradle 引入java-websocket依赖

    dependencies{
      implementation 'org.java-websocket:Java-WebSocket:1.3.0'
    }
    
    页面代码

    activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        >
    
        <ScrollView
            android:id="@+id/svChat"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1">
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:orientation="vertical">
    
                <Spinner
                    android:id="@+id/spDraft"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />
    
                <!-- ws://192.168.1.104:80/JSR356-WebSocket/websocket/ -->
                <!-- ws://192.168.1.104:8887 -->
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
    
                    <EditText
                        android:id="@+id/etAddress"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="4" />
    
                    <Spinner
                        android:id="@+id/spAddress"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="2" />
                </LinearLayout>
    
                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:orientation="horizontal">
                    <!--选择登录用户-->
                    <EditText
                        android:id="@+id/etloginName"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="4"
                        android:hint="选着登录名" /><!--Jack-->
                    <Spinner
                        android:id="@+id/sploginName"
                        android:layout_width="0dp"
                        android:layout_height="match_parent"
                        android:layout_weight="2" />
                </LinearLayout>
    
                <Button
                    android:id="@+id/btnConnect"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="连接" />
    
                <Button
                    android:id="@+id/btnClose"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="断开" />
    
                <EditText
                    android:id="@+id/etDetails"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:background="@null"
                    android:focusable="false"
                    android:focusableInTouchMode="false"
                    android:paddingTop="5dp"
                    android:paddingBottom="5dp"
                    android:textSize="13dp" />
    
                <Button
                    android:id="@+id/btnClearDetails"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="清除聊天记录" />
            </LinearLayout>
        </ScrollView>
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
    
            <Spinner
                android:id="@+id/spName"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:layout_weight="3"/>
    
            <!--<EditText
                android:id="@+id/etName"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:hint="发送对象"
                android:text=""
                android:layout_weight="1"/>--><!--Jack-->
    
            <EditText
                android:id="@+id/etMessage"
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:hint="发送消息内容"
                android:layout_weight="4"/>
    
            <Button
                android:id="@+id/btnSend"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:text="发送"/>
        </LinearLayout>
    </LinearLayout>
    
    
    逻辑代码

    MainActivity.java

    package com.dist.myapplication;
    
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.ArrayAdapter;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.ScrollView;
    import android.widget.Spinner;
    
    import org.java_websocket.WebSocketImpl;
    import org.java_websocket.client.WebSocketClient;
    import org.java_websocket.drafts.Draft;
    import org.java_websocket.drafts.Draft_10;
    import org.java_websocket.drafts.Draft_17;
    import org.java_websocket.drafts.Draft_75;
    import org.java_websocket.drafts.Draft_76;
    import org.java_websocket.handshake.ServerHandshake;
    
    import java.net.URI;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    
        private ScrollView svChat;
        private Spinner spDraft;
        private EditText etAddress;
        private Spinner spAddress;
    
        private Spinner sploginName;
        private EditText etloginName;
    
        private Button btnConnect;
        private Button btnClose;
        private EditText etDetails;
        private Button btnClearDetails;
    
        private Spinner spName;
        //private EditText etName;
        private EditText etMessage;
        private Button btnSend;
    
        private WebSocketClient client;// 连接客户端
        private DraftInfo selectDraft;// 连接协议
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            svChat = (ScrollView) findViewById(R.id.svChat);
            spDraft = (Spinner) findViewById(R.id.spDraft);
            etAddress = (EditText) findViewById(R.id.etAddress);
            spAddress = (Spinner) findViewById(R.id.spAddress);
    
            sploginName = (Spinner) findViewById(R.id.sploginName);
            etloginName = (EditText) findViewById(R.id.etloginName);
    
            btnConnect = (Button) findViewById(R.id.btnConnect);
            btnClose = (Button) findViewById(R.id.btnClose);
            etDetails = (EditText) findViewById(R.id.etDetails);
            btnClearDetails = (Button) findViewById(R.id.btnClearDetails);
    
            spName = (Spinner) findViewById(R.id.spName);
            //etName = (EditText) findViewById(R.id.etName);
            etMessage = (EditText) findViewById(R.id.etMessage);
            btnSend = (Button) findViewById(R.id.btnSend);
    
            DraftInfo[] draftInfos = {new DraftInfo("WebSocket协议Draft_17", new Draft_17()), new DraftInfo
                    ("WebSocket协议Draft_10", new Draft_10()), new DraftInfo("WebSocket协议Draft_76", new Draft_76()), new
                    DraftInfo("WebSocket协议Draft_75", new Draft_75())};// 所有连接协议
            selectDraft = draftInfos[0];// 默认选择第一个连接协议
    
            ArrayAdapter<DraftInfo> draftAdapter = new ArrayAdapter<DraftInfo>(this, android.R.layout
                    .simple_spinner_item, draftInfos);
            spDraft.setAdapter(draftAdapter);
            spDraft.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                    selectDraft = (DraftInfo) spDraft.getItemAtPosition(position);// 选择连接协议
    
                    etDetails.append("当前连接协议:" + selectDraft.draftName + "\n");
    
                    Log.e("wlf", "选择连接协议:" + selectDraft.draftName);
                }
    
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    selectDraft = null;// 清空
    
                    Log.e("wlf", "未选择任何连接协议");
                }
            });
    
            ServerInfo[] serverInfos = {new ServerInfo("连接内网web后台", "ws://192.168.2.114:8887"),new ServerInfo("连接外网web后台", "ws://129.204....:8887")};// 所有连接后台//外网的自己放到服务器上
            etAddress.setText(serverInfos[0].serverAddress);// 默认选择第一个连接协议
    
            ArrayAdapter<ServerInfo> serverAdapter = new ArrayAdapter<ServerInfo>(this, android.R.layout
                    .simple_spinner_item, serverInfos);
            spAddress.setAdapter(serverAdapter);
            spAddress.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    
                    ServerInfo selectServerInfo = (ServerInfo) spAddress.getItemAtPosition(position);// 选择连接后台
                    etAddress.setText(selectServerInfo.serverAddress);
    
                    etDetails.append("当前连接后台:" + selectServerInfo.serverName + "\n");
    
                    Log.e("wlf", "当前连接后台:" + selectServerInfo.serverName);
                }
    
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    selectDraft = null;// 清空
    
                    Log.e("wlf", "未选择任何连接后台");
                }
            });
    
            UserNameInfo[] loginNameInfo = {new UserNameInfo("老邓", "老邓"), new UserNameInfo("老郑", "老郑"),new UserNameInfo("小金鱼", "小金鱼"),
                    new UserNameInfo("张三", "张三"),new UserNameInfo("李四", "李四"),new UserNameInfo("王二", "王二")};// 登录对象
            etloginName.setText(loginNameInfo[0].name);// 默认选择第一个用户登录
    
            ArrayAdapter<UserNameInfo> loginNameAdapter = new ArrayAdapter<UserNameInfo>(this, android.R.layout
                    .simple_spinner_item, loginNameInfo);
            sploginName.setAdapter(loginNameAdapter);
            sploginName.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    
                    UserNameInfo selectloginNameInfo = (UserNameInfo) sploginName.getItemAtPosition(position);// 选择连接后台
                    etloginName.setText(selectloginNameInfo.name);
    
                    etDetails.append("当前登录用户名:" + selectloginNameInfo.loginName + "\n");
    
                    Log.e("wlf", "当前登录用户名:" + selectloginNameInfo.loginName);
                }
    
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                    etloginName = null;// 清空
    
                    Log.e("wlf", "未选任何登录对象");
                }
            });
    
            UserNameInfo[] userNameInfo = {new UserNameInfo("all", "all"),new UserNameInfo("老邓", "老邓"), new UserNameInfo("老郑", "老郑"),new UserNameInfo("小金鱼", "小金鱼"),
                    new UserNameInfo("李四", "李四"), new UserNameInfo("张三", "张三"), new UserNameInfo("王二", "王二")};// 要发送的对象
    
            ArrayAdapter<UserNameInfo> userNameAdapter = new ArrayAdapter<UserNameInfo>(this, android.R.layout
                    .simple_spinner_item, userNameInfo);
            spName.setAdapter(userNameAdapter);
            spName.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
    
                    UserNameInfo selectuserNameInfo = (UserNameInfo) spName.getItemAtPosition(position);// 选择连接后台
                   // etName.setText(selectuserNameInfo.name);
    
                    etDetails.append("发送对象:" + selectuserNameInfo.loginName + "\n");
    
                    Log.e("wlf", "发送对象:" + selectuserNameInfo.loginName);
                }
    
                @Override
                public void onNothingSelected(AdapterView<?> parent) {
                   // etName = null;// 清空
    
                    Log.e("wlf", "未选任何发送对象");
                }
            });
    
            btnConnect.setOnClickListener(this);
            btnClearDetails.setOnClickListener(this);
            btnClose.setOnClickListener(this);
            btnSend.setOnClickListener(this);
    
            WebSocketImpl.DEBUG = true;
            System.setProperty("java.net.preferIPv6Addresses", "false");
            System.setProperty("java.net.preferIPv4Stack", "true");
        }
    
        @Override
        public void onClick(View v) {
            switch (v.getId()) {
                case R.id.btnConnect:
                    try {
                        if (selectDraft == null) {
                            return;
                        }
                        if(etloginName == null){
                            return;
                        }
                        String address = etAddress.getText().toString().trim();
                        if (address.contains("JSR356-WebSocket")) {
                            //address += etName.getText().toString().trim();
                        }
                        Log.e("wlf", "连接地址:" + address);
                        client = new WebSocketClient(new URI(address), selectDraft.draft) {
                            @Override
                            public void onOpen(final ServerHandshake serverHandshakeData) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        etDetails.append("已经连接到服务器【" + getURI() + "】\n");
    
                                        Log.e("wlf", "已经连接到服务器【" + getURI() + "】");
    
                                        spDraft.setEnabled(false);
                                        etAddress.setEnabled(false);
                                        spAddress.setEnabled(false);
                                        etloginName.setEnabled(false);
                                        sploginName.setEnabled(false);
    
                                        btnConnect.setEnabled(false);
                                        //etName.setEnabled(false);
    
                                        spName.setEnabled(true);
                                        btnClearDetails.setEnabled(true);
                                        btnClose.setEnabled(true);
                                        btnSend.setEnabled(true);
                                    }
                                });
                            }
    
                            @Override
                            public void onMessage(final String message) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        etDetails.append("获取到服务器信息【" + message + "】\n");
    
                                        Log.e("wlf", "获取到服务器信息【" + message + "】");
                                    }
                                });
                            }
    
                            @Override
                            public void onClose(final int code, final String reason, final boolean remote) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        etDetails.append("断开服务器连接【" + getURI() + ",状态码: " + code + ",断开原因:" + reason +
                                                "】\n");
    
                                        Log.e("wlf", "断开服务器连接【" + getURI() + ",状态码: " + code + ",断开原因:" + reason + "】");
    
                                        spDraft.setEnabled(true);
                                        etAddress.setEnabled(true);
                                        spAddress.setEnabled(true);
                                        etloginName.setEnabled(true);
                                        sploginName.setEnabled(true);
    
                                        btnConnect.setEnabled(true);
                                        //etName.setEnabled(true);
    
                                        spName.setEnabled(false);
                                        btnClearDetails.setEnabled(true);
                                        btnClose.setEnabled(false);
                                        btnSend.setEnabled(false);
                                    }
                                });
                            }
    
                            @Override
                            public void onError(final Exception e) {
                                runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        etDetails.append("连接发生了异常【异常原因:" + e + "】\n");
    
                                        Log.e("wlf", "连接发生了异常【异常原因:" + e + "】");
    
                                        spDraft.setEnabled(true);
                                        etAddress.setEnabled(true);
                                        btnConnect.setEnabled(true);
                                        //etName.setEnabled(true);
    
                                        btnClearDetails.setEnabled(false);
                                        btnClose.setEnabled(false);
                                        btnSend.setEnabled(false);
                                    }
                                });
                            }
                        };
                        client.connect();
                        new Thread(){
                            @Override
                            public void run(){
                                super.run();
                                try {
                                    Thread.sleep(200);
                                    if (client != null) {
                                        client.send(etloginName.getText().toString().trim());
                                        svChat.post(new Runnable() {
                                            @Override
                                            public void run() {
                                                svChat.fullScroll(View.FOCUS_DOWN);
                                                etMessage.setText("");
                                                etMessage.requestFocus();
                                            }
                                        });
                                    }
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                            }
                        }.start();
    
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                case R.id.btnClearDetails:
                    if (etDetails.getText().toString() != null && etDetails.getText().length()>0) {
                        etDetails.setText("");
                    }
                    break;
                case R.id.btnClose:
                    if (client != null) {
                        client.close();
                    }
                    break;
                case R.id.btnSend:
                    try {
                        if (client != null) {
                            //client.send(etName.getText().toString().trim() + "说:" + etMessage.getText().toString().trim());
                            //client.send(etName.getText().toString().trim() +"@"+etMessage.getText().toString().trim());
                            client.send(spName.getSelectedItem().toString().trim() +"@"+etMessage.getText().toString().trim());
                            svChat.post(new Runnable() {
                                @Override
                                public void run() {
                                    svChat.fullScroll(View.FOCUS_DOWN);
                                    etMessage.setText("");
                                    etMessage.requestFocus();
                                }
                            });
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
            }
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            if (client != null) {
                client.close();
            }
        }
    
        private class DraftInfo {
    
            private final String draftName;
            private final Draft draft;
    
            public DraftInfo(String draftName, Draft draft) {
                this.draftName = draftName;
                this.draft = draft;
            }
    
            @Override
            public String toString() {
                return draftName;
            }
        }
    
        private class ServerInfo {
    
            private final String serverName;
            private final String serverAddress;
    
            public ServerInfo(String serverName, String serverAddress) {
                this.serverName = serverName;
                this.serverAddress = serverAddress;
            }
    
            @Override
            public String toString() {
                return serverName;
            }
        }
    
        private class UserNameInfo {
    
            private final String loginName;
            private final String name;
    
            public UserNameInfo(String loginName, String name) {
                this.loginName = loginName;
                this.name = name;
            }
    
            @Override
            public String toString() {
                return loginName;
            }
        }
    }
    
    

    现在就可以完成H5和Andorid通信啦

    相关文章

      网友评论

        本文标题:史上最全Websocket通信测试

        本文链接:https://www.haomeiwen.com/subject/sccnwqtx.html