WebSocket基础教程

什么是websocket

哔哩哔哩:https://www.bilibili.com/video/BV1TKfGYeE2G/

websocket概述


1、什么是websocket


  • WebSocket 是一种网络通信协议,就像http协议一样
    • ws
  • 为什么需要websocket
  • websocket的缺点

2、websocket在脚本开发中的应用场景


  • 主动控制脚本
  • 批量主动控制脚本 :广播
  • 脚本之间协作
  • 网络验证

3、websocket的客户端和服务端的简单介绍


  • 什么是服务端
  • 什么是客户端

– HTML5 WebSocket –

1、创建WebSocket连接


var Socket = new WebSocket(url, [protocol] );

2、HTML5客户端WebSocket事件


事件事件处理程序描述
openSocket.onopen连接建立时触发
messageSocket.onmessage客户端接收服务端数据时触发
errorSocket.onerror通信发生错误时触发
closeSocket.onclose连接关闭时触发
    Socket.onopen = function (){
​
        console.log('连接已经建立')
​
    }
​
    Socket.onmessage = function (evt){
​
        // console.log(evt.data)
​
        mycallback(evt.data)
​
    }
​
    Socket.onclose = function(){
​
        console.log("连接已断开")
​
    }

3、HTML5客户端WebSocket方法


方法描述
Socket.send()使用连接发送数据
Socket.close()关闭连接
Socket.send('["事件名",数据]');
​
Socket.send(JSON.stringify(['test',{
            msg: '你好',
            to: 1
        }]));

4、socket.io的使用方法


var socket = io("http://192.168.31.237:8080", { transports: ['websocket']});
    
    socket.on('connect', function () {
        console.log('连接成功')
    });
    socket.on('close', function () {
        console.log('连接关闭')
    });
    
    
    function send() {
            
            //发送消息
            ws.emit('test',{
                msg: "你好"
            })
    }
    

– Autojs WebSocket –

1、Autojs.pro版本websocket功能


// 新建一个WebSocket
// 指定web socket的事件回调在当前线程(好处是没有多线程问题要处理,坏处是不能阻塞当前线程,包括死循环)
// 不加后面的参数则回调在IO线程
​
var ws = web.newWebSocket("ws://192.168.31.237:8080", {
    eventThread: 'this'
});
​
​
// 监听他的各种事件
ws.on("open", (res, ws) => {
​
    log("WebSocket已连接");
​
}).on("text", (text, ws) => {
​
    log("收到文本消息: ", text);
​
}).on("closing", (code, reason, ws) => {
​
        log("WebSocket关闭中");
​
}).on("closed", (code, reason, ws) => {
    
    log("WebSocket已关闭: code = %d, reason = %s", code, reason);
​
});
​
// setTimeout(() => {
//     // 8秒后断开WebSocket
//     log("断开WebSocket");
//     // 1000表示正常关闭
//     ws.close(1000, null);
// }, 3000);
​
events.on("exit", function(){
​
    ws.close(1000, null);
    
});
​
setInterval(()=>{}, 1000);
​
​
// toast('123')

2、Autojs.pro版本websocket通信


ws.send(JSON.stringify(["test",{
        msg: '你好',
        to: 1
}]));

3、Autojs.pro版本websocket处理接收的消息


function mycallback(data) {
        
            var start = data.indexOf('[')  // [ 第一次出现的位置  1
            var start1 = data.indexOf('{') // 1
​
            if (start < 0) {
                start = start1;
            }
            if  (start >=0 && start1 >=0) {
                start = Math.min(start, start1);
            }
​
            if (start >= 0) {
                // console.log(data)
                var json = data.substr(start);// 截取
                var json = JSON.parse(json);
                
                
                if (json instanceof  Array) {
                    eval(json[0]+"("+json[1]+")")
                }
​
            }
    }

4、Autojs4.1版本websocket功能的封装


"ui";
ui.layout(
    <vertical>
        <button id="btn1" text="第一个按钮"/>
        <button text="第二个按钮"/>
    </vertical>
);
​
​
importClass('java.lang.StringBuffer')
importClass('java.io.InputStream');
importClass('java.io.InputStreamReader');
importClass('java.io.OutputStream');
importClass('java.io.PrintWriter');
importClass('java.net.Socket');
​
ui.btn1.click(function(){
    threads.start(function(){
        toast('第一个按钮被点击')
    });
})
​
​
​
events.on("exit", function(){
    // Thread.interrupt();
    // sleep(1000)
    closeWebsoket()
    log('断开了')
});
var socket;
var outputStream;
var inputStream;
var printWriter;
​
var info = "";
var ReadData = "";
var Read = 0;
​
var Thread = threads.start(function(){
    
​
    Socket连接('192.168.31.237',8080)
    //在新线程执行的代码
    while (true) {
​
        try {
    
            Read = inputStream.read();
            log(Read)
        } catch (errpr) {
    
            log("服务器异常")
            closeWebsoket()
            break;
        }
    
        info = String.fromCharCode(Read);
        ReadData += info;
        
        if(ReadData.indexOf('42') != -1){
            log(ReadData)
            ReadData = '' 
        }
​
        if(ReadData.indexOf('[') != -1 && ReadData.indexOf(']') != -1 && ReadData.indexOf('callback') != -1){
            log(ReadData)
            mycallback(ReadData)
            ReadData = '' 
        }
        
    }
});
​
function connect_callback(data) {
​
    toast('我的fd是'+data)
​
}
​
function mycallback(data) {
        
    var start = data.indexOf('[')  // [ 第一次出现的位置  1
    var start1 = data.indexOf('{') // 1
​
    if (start < 0) {
        start = start1;
    }
    if  (start >=0 && start1 >=0) {
        start = Math.min(start, start1);
    }
​
    if (start >= 0) {
        // console.log(data)
        var json = data.substr(start);// 截取
        var json = JSON.parse(json);
        
        // log(json[0],json[1])
        if (json instanceof  Array) {
            eval(json[0]+"("+json[1]+")")
        }
        
    }
}
​
function Socket连接(host, port) {
    //连接成功 退出循环
    while (true) {
​
        log("执行连接")
        try {
            socket = new Socket(host, port);
            if (socket != null) {
                log(socket);
                break;
            }
            
​
            sleep(2000);
        } catch (errpr) {
​
            for (var i = 60; i > 0; i--) {
                toast("服务器异常,等待倒计时" + i);
                sleep(2000)
            }
​
        }
    }
​
    outputStream = socket.getOutputStream();
    printWriter = new PrintWriter(outputStream);
    inputStream = socket.getInputStream();
    handshake(host,port)
}
​
function handshake(host,port){
    var sb = new StringBuffer("GET http://"+host+":"+port+"/ HTTP/1.1\r\n");
    // 以下为请求头 
    sb.append("Host: "+host+":"+port+"\r\n");
    sb.append("User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36\r\n");
    sb.append("Accept-Language: zh-CN,zh;q=0.9\r\n");
    // 注意这里不要使用压缩 否则返回乱码
    sb.append("Connection: Upgrade\r\n");
    sb.append("Upgrade: websocket\r\n");
    sb.append("Sec-WebSocket-Key: psFrOOt6Tf0kErwzzVgMGA==\r\n");
    sb.append("Sec-WebSocket-Version: 13\r\n");
    sb.append("Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n");
    sb.append("\r\n");
    printWriter.print(sb.toString());
    printWriter.flush();
}
​
function closeWebsoket()
{
    outputStream.close();
    inputStream.close();
    socket.close();
    // socket=null;
}

5、Autojs4.1版本websocket连接服务器


importClass('java.lang.StringBuffer')
importClass('java.io.InputStream');
importClass('java.io.InputStreamReader');
importClass('java.io.OutputStream');
importClass('java.io.PrintWriter');
importClass('java.net.Socket');

var socket;
var outputStream;
var inputStream;
var printWriter;


function Socket连接(host, port) {
    //连接成功 退出循环
    while (true) {

        log("执行连接")
        try {
            socket = new Socket(host, port);
            if (socket != null) {
                log(socket);
                break;
            }
            

            sleep(2000);
        } catch (errpr) {

            for (var i = 60; i > 0; i--) {
                toast("服务器异常,等待倒计时" + i);
                sleep(2000)
            }
        }
    }

    outputStream = socket.getOutputStream();
    printWriter = new PrintWriter(outputStream);
    inputStream = socket.getInputStream();
    handshake(host,port)
}

function handshake(host,port){
    var sb = new StringBuffer("GET http://"+host+":"+port+"/ HTTP/1.1\r\n");
    // 以下为请求头 
    sb.append("Host: "+host+":"+port+"\r\n");
    sb.append("User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36\r\n");
    sb.append("Accept-Language: zh-CN,zh;q=0.9\r\n");
    // 注意这里不要使用压缩 否则返回乱码
    sb.append("Connection: Upgrade\r\n");
    sb.append("Upgrade: websocket\r\n");
    sb.append("Sec-WebSocket-Key: psFrOOt6Tf0kErwzzVgMGA==\r\n");
    sb.append("Sec-WebSocket-Version: 13\r\n");
    sb.append("Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits\r\n");
    sb.append("\r\n");
    printWriter.print(sb.toString());
    printWriter.flush();
}

6、Autojs4.1版本websocket关闭功能


events.on("exit", function(){
    // Thread.interrupt();
    // sleep(1000)
    closeWebsoket()
    log('断开了')
});

function closeWebsoket()
{
    outputStream.close();
    inputStream.close();
    socket.close();
}

7、Autojs4.1版本websocket接收消息


    while (true) {

        try {
    
            Read = inputStream.read();
            log(Read)
        } catch (errpr) {
    
            log("服务器异常")
            closeWebsoket()
            break;
        }
    
        info = String.fromCharCode(Read);
        ReadData += info;
        
        if(ReadData.indexOf('42') != -1){
            log(ReadData)
            ReadData = '' 
        }

        if(ReadData.indexOf('[') != -1 && ReadData.indexOf(']') != -1 && ReadData.indexOf('callback') != -1){
            log(ReadData)
            mycallback(ReadData)
            ReadData = '' 
        }
        
    }

8、Autojs4.1版本websocket在UI界面下运行


"ui";
ui.layout(
    <vertical>
        <button id="btn1" text="关闭ws"/>
        <button id="btn2"  text="发送消息"/>
    </vertical>
);

//监听btn1的点击事件
ui.btn1.click(function(){
    // toast("按钮被点击了")
    closeWebsoket()
})

//监听btn2的点击事件
ui.btn2.click(function(){
    toast("按钮被点击了")
    // closeWebsoket()
})

– Websocket通讯实例演示 –

1、通讯实例讲解


2、准备开发环境


  • linux
  • 宝塔面板
  • swoole4.5.11
  • thinkphp
  • think-swoole3.0.9
  • layui

3、开发网页端设备列表功能


4、创建设备数据库


5、开发后台数据接口


6、前后端websocket通讯


7、动态添加数据到数据库


8、完善主控端的上线信息


9、完善客户端的上线流程


10、完善手机端脚本上线流程


11、手机上线过程中的bug修复


12、完善客户端下线流程


13、服务器向客户端发送字符串指令


14、如何防止layui按钮刷新页面


15、服务器向客户端发送代码指令

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧