webscoket学习

news2024/11/23 21:09:36

webscoket基本使用 

WebSocket - Web API 接口参考 | MDN

 使用node编写webscoket服务

nodejs-webscoket 在github的地址↓ 

GitHub - sitegui/nodejs-websocket: A node.js module for websocket server and client

ws和socket.io 是wbscket的两个库

仓库地址:learn-webscoket: webscoket学习 ,前台使用原生写法 基于 webscoket 类

ws库+html 实现聊天

后台使用的是ws库:

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8088 }); // websocket的端口

let i = 0
wss.on('connection', function connection(ws) {
    i++
    console.log("当前链接人数是" + i);
    ws.on('message', function incoming(message) {
        console.log('服务端接受到数据:', message);
        message = message.toString()
        // console.log(message.toString());
        // 广播给所有用户
        wss.clients.forEach(function each(client) {
            if (client.readyState === WebSocket.OPEN) {
                // client.send(JSON.stringify(message));
                client.send(message);
            }
        });
    });
    // ws.send('something');
});

前台 基于WebSocket 类实现:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>

    </style>
</head>

<body>
    <input id="message-text" type="text">
    <button id="send">发送</button>
    <button id="close">关闭</button>
    <div id="message-list"></div>
</body>
<script type="text/javascript">
    var ws = new WebSocket('ws://localhost:8088');
    ws.onopen = function (evt) { // 连接建立触发
        console.log('建立连接,状态:' + ws.readyState);
    };

    ws.onmessage = function (evt) { // 服务端返回数据触发
        // console.log(String.toString(evt.data));
        var data = JSON.parse(evt.data)
        console.log(data);
        console.log("状态:" + ws.readyState + ";服务端返回数据:", data);
        var list = document.getElementById("message-list");
        list.insertAdjacentHTML("beforeEnd", `<div>${data.message}</div>`);
    };

    ws.onerror = function (evt) { // 通信发生错误触发
        console.log(evt);
        console.log('发生错误,状态:' + ws.readyState);
    };

    ws.onclose = function (evt) { // 连接关闭触发
        console.log(evt);
        console.log("连接关闭,状态:", ws.readyState);
    };

    document.getElementById("send").onclick = function () {
        var val = document.getElementById("message-text").value
        var data = {
            message: val
        }
        console.log(data);
        ws.send(JSON.stringify(data)); // 推送数据到服务器, 数据类型必须为字符串
        // console.log('我发送成功了');
    }

    document.getElementById("close").onclick = function () {
        ws.close(); // 关闭连接
    }
</script>

</html>

socket.io + html实现聊天(群聊)

参考:scoket.io实现群聊、私聊_小宇宙chris_310的博客-CSDN博客_scoketio

js部分:

const app = require('express')()
const http = require("http").Server(app);
const io = require("socket.io")(http,{
    cors:true
});

http.listen(3000, () => {
    console.log(`服务启动成功,地址是 http://127.0.0.1:3000`);
})
console.log(__dirname);
app.get('/', (req, res) => {
    res.sendFile(__dirname + '/groupChat.html')
})

io.on("connection", (socket) => {
    console.log('用户建立了链接');
    // 接收客户端发来的数据
    socket.on('chat message', function (msg) {
        console.log('message:' + msg);
        io.emit('receiveMessage', msg)
    })
    // 如果是断开socket请求,就会触发下面的代码
    socket.on('disconnect', function () {
        console.log('user disconnect')         
    })
});

html部分:

<!doctype html>
<html>

<head>
    <title>Socket.IO chat</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font: 13px Helvetica, Arial;
        }

        form {
            background: #000;
            padding: 3px;
            position: fixed;
            bottom: 0;
            width: 100%;
        }

        form input {
            border: 0;
            padding: 10px;
            width: 80%;
            margin-right: .5%;
        }

        form button {
            width: 19%;
            background: rgb(130, 224, 255);
            border: none;
            padding: 10px;
        }

        #messages {
            list-style-type: none;
            margin: 0;
            padding: 0;
        }

        #messages li {
            padding: 5px 10px;
        }
    </style>
</head>

<body>
    <ul id="messages">
    </ul>
    <form action="">
        <input id="m" autocomplete="off" /><button>Send</button>
    </form>
</body>
<!-- <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"
    integrity="sha384-/KNQL8Nu5gCHLqwqfQjA689Hhoqgi2S84SNUxC3roTe4EhJ9AfLkp8QiQcU8AMzI"
    crossorigin="anonymous"></script> -->

<script src="/socket.io/socket.io.js"></script>
<script>
    // 这样就加载了 socket.io-client。 socket.io-client 暴露了一个 io 全局变量,然后连接服务器。
    //请注意我们在调用 io() 时没有指定任何 URL,因为它默认将尝试连接到提供当前页面的主机。
    var username = prompt('请输入用户名')
    var socket = io('http://127.0.0.1:3000');
    var form = document.querySelector('form');
    var val = document.querySelector('#m');
    var messages = document.querySelector('#messages')
    // var messages=document.querySelector('#messages')
    form.onsubmit = function () {
        var obj = {
            username: username,
            mes: val.value
        }
        socket.emit('chat message', JSON.stringify(obj));
        // messages.innerHTML += `
        //     <li style="text-align:right;color:blue;">${val.value}<li>
        // `;
        val.value = '';
        // console.log(obj);
        // console.log(messages);
        return false;//阻止表单默认行为
    }
    //接收后端发来的消息
    socket.on('receiveMessage', function (data) {
        // console.log(data);
        var obj = JSON.parse(data);
        if (obj.username == username)
            //不渲染自己发送的消息
            return;
        //渲染别人发送的消息
        messages.innerHTML += `
            <li style="text-align:left;color:red;">${obj.username}:${obj.mes}<li>`;
    })
</script>

</html>

socket.io + html实现聊天(私聊)

js部分:

const app = require('express')(); // 获取express模块实例
const http = require('http').Server(app); // 将express模块实例作为回调构建http模块实例
const io = require('socket.io')(http, {
    cors: true
}); // 将http模块实例作为回调构建socket.io模块实例

// 使用http模块开启后端服务(原生node+express的结合)
http.listen(3000, function () {
    console.log('listening on http://127.0.0.1:3000')
})
// 设置路由,构建后端接口
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/privateChat.html'); // 将根目录下的index.html发送到前端
})
var users = {}; // 保存所有用户的键值对集合
io.on('connection', function (socket) {
    socket.on('con', function (msg) {
        var obj = JSON.parse(msg) // 获取连接的用户信息
        users[obj.username] = socket.id; // 将当前用户名和对应的链接id进行保存
        console.log('有新的链接,最新用户集合为:', users)
    })
    // 接收客户端发来的数据
    socket.on('chat message', function (msg) {
        var obj = JSON.parse(msg) // 获取连接的用户信息
        console.log('obj:', obj)
        if (users[obj.toWho] == undefined) {
            let respmes = {
                usernamez: '系统信息',
                mes: '抱歉【' + obj.toWho + '】还未上线'
            }
            io.to(socket.id).emit('receiveMessage', JSON.stringify(respmes)); // 将消息发给当前用户
        } else { // 说明目标用户存在
            let respmes = {
                usernamez: obj.username,
                mes: obj.mes
            }
            io.to(users[obj.toWho]).emit('receiveMessage', JSON.stringify(respmes)); // 通过id将信息转发给指定的对象
        }
    })
    // 如果是断开socket请求,就会触发下面的代码
    socket.on('disconnect', function () {
        console.log('user disconnected')
    })
})

html部分:

<html>

<head>
    <title>Socket.IO chat</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font: 13px Helvetica, Arial;
        }

        form {
            background: #000;
            padding: 3px;
            position: fixed;
            bottom: 0;
            width: 100%;
        }

        form input {
            border: 0;
            padding: 10px;
            width: 80%;
            margin-right: .5%;
        }

        form button {
            width: 19%;
            background: rgb(130, 224, 255);
            border: none;
            padding: 10px;
        }

        #messages {
            list-style-type: none;
            margin: 0;
            padding: 0;
        }

        #messages li {
            padding: 5px 10px;
        }
    </style>
</head>

<body>
    <script src="https://cdn.socket.io/4.5.4/socket.io.min.js"
        integrity="sha384-/KNQL8Nu5gCHLqwqfQjA689Hhoqgi2S84SNUxC3roTe4EhJ9AfLkp8QiQcU8AMzI"
        crossorigin="anonymous"></script>
    <!-- <script src="/socket.io/socket.io.js"></script> -->
    <script>
        // 这样就加载了 socket.io-client。 socket.io-client 暴露了一个 io 全局变量,然后连接服务器。
        //请注意我们在调用 io() 时没有指定任何 URL,因为它默认将尝试连接到提供当前页面的主机。
        window.onload = function () {
            var username = prompt("请输入你的用户名:", "");
            var who = prompt("你要和谁聊天?:", "");
            document.body.innerHTML = `<h3>当前用户:${username}, 和${who}聊天中...</h3>` + document.body.innerHTML;
            var socket = io("http://localhost:3000/");
            var form = document.querySelector("form");
            var val = document.querySelector("#m");
            //先和服务端建立连接
            let conobj = {
                username: username,
                toWho: who,
            }
            socket.emit('con', JSON.stringify(conobj));
            //表单提交事件
            form.onsubmit = function () {
                let obj = {
                    username: username,
                    toWho: who,
                    mes: val.value
                }
                socket.emit('chat message', JSON.stringify(obj));
                // messages.innerHTML += `
                // <li style="text-align:right;color:blue;">${val.value}<li>`;
                val.value = "";
                return false;
            }
            //接收后端发来的消息
            socket.on("receiveMessage", function (data) {
                var obj = JSON.parse(data);
                console.log(obj)
                if (obj.username == username) return; //不接受自己发的消息
                messages.innerHTML += `
<li style="text-align:left;color:red;">${obj.usernamez}:${obj.mes}<li>`;
            })
        }
    </script>
    <ul id="messages"></ul>
    <form action="">
        <input id="m" autocomplete="off" /><button>Send</button>
    </form>
</body>

</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/45929.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Scala系列-5、scala中的泛型、actor、akka

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 传送门&#xff1a;大数据系列文章目录 目录scala的 泛型给方法定义泛型给类定义泛型泛型的上下界泛型中 非变 协变 和 逆变scala中actor相关内…

echarts中tooltip设为渐变色与模糊背景滤镜

关于echarts各项内容&#xff08;包括图表面积区域&#xff09;设为渐变色已在上篇文章里全部阐述&#xff1a; echarts折线图与柱状图等绘成渐变色的方法 单独将tooltip拉出来再写一篇&#xff0c;是因为用formatter配合超文本的形式在echarts的配置项中&#xff0c;于自定义样…

Python使用magic判断文件MIME类型

文章目录官网安装使用判断文件的MIME类型支持中文的代码问题官网 GitHub - ahupp/python-magic: A python wrapper for libmagic 安装 pip install python-magic pip install python-magic-bin使用 判断文件的MIME类型 代码 # encodingutf-8 import magic #pip install pyt…

希尔贝壳受邀参加IEEE自动语音识别与理解研讨会-ASRU 2021

ASRU 2021 IEEE Automatic Speech Recognition and Understanding Workshop&#xff08;2021年IEEE自动语音识别与理解研讨会&#xff0c;以下简称ASRU&#xff09;&#xff0c;将于2021年12月13日至17日在哥伦比亚卡塔赫纳举行。 ASRU 研讨会是IEEE语音和语言处理技术委员会(…

领悟《信号与系统》之 周期信号的傅里叶变换计算

周期信号的傅里叶变换计算一、周期信号的傅里叶变换存在的条件二、周期信号的傅里叶变换例题&#xff1a;一、周期信号的傅里叶变换存在的条件 典型非周期信号&#xff08;如指数信号&#xff0c;矩形信号等&#xff09;都是满足绝对可积&#xff08;或绝对可和&#xff09;条…

IDEA的日常快捷键大全

更多内容在&#xff1a;https://javaxiaobear.gitee.io/ ​​​​​​第1组&#xff1a;通用型 说明 快捷键 复制代码-copy ctrl c 粘贴-paste ctrl v 剪切-cut ctrl x 撤销-undo ctrl z 反撤销-redo ctrl shift z 保存-save all ctrl s 全选-select all …

(2)点云库处理学习——剔除点云值

1、主要参考 1.1参考地址 (1) 点云离群点剔除 — open3d python_Coding的叶子的博客-CSDN博客_离群点去除 (2) open3d之点云异常值去除&#xff08;笔记5&#xff09;_Satellite_H的博客-CSDN博客 (3)斯坦福经典兔子的点云数据下载地址 下载地址 Model : Bunny 1.2兔子…

3D视觉识别案例:3D无序棒料抓取,阀体圆环上下料,电机定子上料

3D无序棒料抓取 某知名汽车行业 项目背景 长春某知名汽车行业&#xff0c;需求3D视觉实现圆形棒材的上料自动化。 作业流程 钢棒依次经过剪切/锯切下料&#xff0c;从深筐中抓取&#xff0c;先放置在V型二次定位平台上&#xff0c;再从平台抓到输送线上&#xff0c;目标工…

[附源码]SSM计算机毕业设计新冠疫苗线上预约系统JAVA

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

超算,先进计算未来的研究方向有哪些?

超算是一个非常有趣的方向&#xff0c;当人们仰天长望思索宇宙大爆炸和起源时&#xff0c;超算便成为了非常重要的一个研究途径&#xff0c;利用超算平台对中国FAST天眼射电望远镜捕捉到的海量信号进行分析和处理&#xff0c;帮助中科院探索发现了诸如脉冲星、最大原子气体、快…

如何将报告从 JasperReports 导入到 FastReport .NET?

FastReport.NET官方版下载 我们在 JasperReports 添加了一个新的导入功能&#xff0c;如果要使用它&#xff0c;需要到 FastReport .NET 设计器中的“文件”菜单并选择“打开...”。在出现的窗口中&#xff0c;选择过滤器“JasperReports 文件 (*.jrxml)”。所选文件将自动转换…

基于Apache-DButils以及Druid(德鲁伊)与数据库交互实现的一个项目:满汉楼

基于Apache-DButils以及Druid(德鲁伊)与数据库交互实现的一个项目&#xff1a;满汉楼 每博一文案 张小贤曾说过: 你不过是做自己喜欢做的事&#xff0c;过自己喜欢过的生活。 若有人因为你喜欢做的事而觉得恶心和取笑你&#xff0c;那是他们的事。是呀&#xff0c;生活是苦&am…

蓝海创意云亮相2022南京融交会,打造沉浸式元宇宙互动体验

11月24日&#xff0c;2022中国&#xff08;南京&#xff09;文化和科技融合成果展览交易会在南京国际展览中心正式开幕&#xff0c;展会聚焦文化数字化战略&#xff0c;集中展示文化数据专网、数字化公共文化服务、“元宇宙”等数字文化新基建、新服务、新场景、新体验。 苏州…

第十三章《集合》第3节:Set集合

Set也是Collection的子接口,它定义了另一种形式的集合,专业上称之为Set集合。Set集合的特点如图13-9所示。 图13-9 Set类型集合 从图13-9可以看出:Set类型的集合就像是一个装苹果的筐子,程序员只要把元素存入这个筐子即可。集合中的元素像是胡乱堆积在一起,因此元素没有索…

迷宫-蓝桥云课,python实现

X 星球的一处迷宫游乐场建在某个小山坡上。它是由 10 \times 101010 相互连通的小房间组成的。 房间的地板上写着一个很大的字母。我们假设玩家是面朝上坡的方向站立&#xff0c;则&#xff1a; LL 表示走到左边的房间&#xff0c;RR 表示走到右边的房间&#xff0c;UU 表示走…

HTTPS —— HTTPS的加密方式

JavaEE传送门JavaEE HTTP —— HTTP 协议中的细节(超详细!!) HTTP —— HTTP 响应详解, 构造 HTTP 请求 目录HTTPS"加密"对称加密非对称加密证书总结HTTPS “加密” 明文: 要传递的原始信息 密文: 经过加密后的信息 密钥: 将明文加密的方法 (在加密和解密中起到…

京东APP技术解密:移动端秒级配置触达平台-Switchquery

原文已同步发表在京东零售技术公众号:mp.weixin.qq.com/s/hvsFwsQHT… 一 背景 随着移动互联网的快速发展&#xff0c;为满足各类用户及人群的体验需求&#xff0c;移动端的开发者们开发了丰富多彩的体验与功能。同时对于快速控制各类功能的切换、灰度&#xff0c;降级等能力…

纠正一下网上文章所说“利用RPC绕过CFG”的错误说法

纠正误区 网上说“利用RPC绕过CFG”的说法是不正确的&#xff0c;我先给出自己的观点&#xff0c;后面再说我的分析。网上有好几篇分析CVE-2021-26411的文章&#xff0c;对绕过CFG一律都说是利用RPC。其实在这个漏洞场景下&#xff0c;攻击者只不过是借助RPC获得执行任意系统函…

Nginx配置Https证书

大致的流程如下 1.申请Https证书,绑定域名信息; 如果您有自己的服务器或者购买云服务器&#xff0c;可在相关方平台申请SSL证书&#xff0c;申请后下载相关证书文件即可&#xff0c;如下图&#xff1a; 解压缩后发现可以得到如下文件&#xff1a; 由于我们要使用Nginx配置SSL…

美团面试应届生第二问:Volatile有什么作用?

文章目录volatile有什么作用&#xff1f;可见性证明指令重排证明不能保证原子性证明Volatile与Synchronized的区别volatile有什么作用&#xff1f; 保证线程的可见性禁止指令重排但是不能保证原子性 可见性证明 有如下静态成员变量num&#xff0c;初始值为0&#xff1b;有两…