IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> WebSocket聊天小例子(附源码) -> 正文阅读

[网络协议]WebSocket聊天小例子(附源码)

WebSocket聊天小例子(附源码)

还记得之前我们用c#写过一个聊天室,但是是cs的,我们都知道现在流行的是bs架构,所以很相似C#用的是socket底层是tcp和udp而websocket其实就是在http的基础上模仿tcp和udp握手和挥手

基于C#的socket聊天室(附源码): https://blog.csdn.net/hello_list/article/details/124075029

原理嘛都差不多,要我说一个文章讲原理不如直接上例子上代码的方便,讲解一下这个小例子就懂了;

这里呢我们使用的是tomcat自带的依赖,所以不用导入,还有一种方法是spring的,这里就不说了;

体验

我们先尝试体验下效果

将Web项目运行起来,一个特别简单的页面,其实页面我们可以去扒就可以,比如csdn的私信页面,拿去用就行,功能还那么个功能,但是我这里主要是功能,就没有扒页面,看完这个例子,完全可以去做一个csdn这样的私信功能;

先看下我这个简陋的页面

image-20220715110103483

我们再看下功能,可简单了,会用吧

输入id点击获取连接;连接成功之后,这个时候id就固定了,我这里直接锁住了

image-20220715110254186

我们再开两个,三个用户我们就连接成功了;

image-20220715110410685

这里也可以看下后端日志

image-20220715110442827

我们可以给在线的用户发送消息,只需要输入对方id,我这里就试着互相发了几条消息:

image-20220715110644954

功能到这里就结束了,我们看下是怎么实现的,简单理解下,可简单了;

服务端

服务端代码,一个java文件就搞定

package servlet;

import java.io.IOException;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

@ServerEndpoint("/webSocket/{sid}")
public class TestWebSocket {

    // 静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static AtomicInteger onlineNum = new AtomicInteger();

    // concurrent包的线程安全Set,用来存放每个客户端对应的WebSocketServer对象。
    private static ConcurrentHashMap<String, Session> sessionPools = new ConcurrentHashMap<>();

    // 发送消息
    public void sendMessage(Session session, String message) throws IOException {
        if (session != null) {
            synchronized (session) {
                // System.out.println("发送数据:" + message);
                session.getBasicRemote().sendText(message);
            }
        }
    }

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "sid") String sid) throws IOException {
        System.out.println("新连接");
        sessionPools.put(sid, session);
        addOnlineCount();
        System.out.println(sid + "加入webSocket!当前人数为" + onlineNum);
        sendMessage(session, "欢迎" + sid + "加入连接!");
    }

    @OnClose
    public void onClose() {
        subOnlineCount();
        System.out.println("连接关闭");
    }

    @OnMessage
    public void onMessage(String message, Session session) throws IOException {
        System.out.println("收到消息");
        System.out.println(message);
        //		session.getBasicRemote().sendText("你好,我是服务端");
        JSONObject jsonObject = (JSONObject) JSON.parse(message);
        System.out.println(jsonObject);
        //		sendMessage(sessionPools.get(jsonObject.get("tsid")), String.valueOf(jsonObject.get("sid"))+"--给你发来消息:"+String.valueOf(jsonObject.get("txt")));
        //		System.out.println( String.valueOf(jsonObject.get("sid"))+"发送消息成功");
        JSONObject jsonObject2 = new JSONObject();
        jsonObject2.put("fromid", String.valueOf(jsonObject.get("sid")));
        jsonObject2.put("text", String.valueOf(jsonObject.get("txt")));
        sendMessage(sessionPools.get(jsonObject.get("tsid")), jsonObject2.toJSONString());
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    // 增加在线人数
    public static void addOnlineCount() {
        onlineNum.incrementAndGet();
    }

    // 减少在线人数
    public static void subOnlineCount() {
        onlineNum.decrementAndGet();
    }

}

客户端,其实就是网页端

所以说前后就两个文件,这里我们在客户端创建一个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>
    </head>

    <body>

        <input type="text" id="sid">
        <button οnclick="lianjie()">请输入id然后点击连接</button>

        <hr>
        <br> 消息输入:
        <input type="text" id="txt" />
        <br> 消息接收人的id:
        <input type="text" id="tsid" />
        <button οnclick="cli()">点击发送</button>

        <br>
        <hr>
        以下是消息区域:
        <div id="app"></div>

        <script>
            var websocket = null;
            function lianjie() {
                //判断当前浏览器是否支持websocket
                if ('WebSocket' in window) {
                    websocket = new WebSocket("ws://localhost:8081/web/webSocket/"+document.getElementById("sid").value);
                } else {
                    alert('当前浏览器 not support websocket')
                }
                //连接发生错误的回调方法
                websocket.onerror = function () {
                    alert("连接发生错误");
                };
                //连接成功建立的回调方法
                websocket.onopen = function () {
                    //websocket.send("hello")
                    alert("连接成功");
                    var sid = document.getElementById("sid")
                    sid.readOnly = true
                    sid.style.backgroundColor='#ddd'
                }
                //接收到消息的回调方法
                websocket.onmessage = function (event) {
                    //console.log("收到服务端消息"+event.data)
                    console.log(event.data)
                    var json = JSON.parse(event.data)
                    innerdiv(json.fromid,json.text)
                }
                //连接关闭的回调方法
                websocket.onclose = function () {
                    setmessageinnerhtml("websocket连接关闭");
                }
                //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
                window.onbeforeunload = function () {
                    closewebsocket();
                }
            }

            //发送消息
            function cli() {
                var sid = document.getElementById("sid")  //发送者id
                var txt = document.getElementById("txt").value  //发送消息
                var tsid = document.getElementById("tsid").value //接收者id
                var m = new Map(); // 空Map
                m.set("sid",sid.value);
                m.set("txt",txt)
                m.set("tsid",tsid)
                json = mapToJson(m)
                console.log(json)
                websocket.send(json)
                innerdiv("我",txt)
            }
            //关闭websocket连接
            function closewebsocket() {
                websocket.close();
            }

            function strMapToObj(strMap){
                var obj= Object.create(null);
                for (var[k,v] of strMap) {
                    obj[k] = v;
                }
                return obj;
            }
            /**
        *map转换为json
        */
            function  mapToJson(map) {
                return JSON.stringify(strMapToObj(map));
            }
            /*
        	添加聊天记录
        */
            function innerdiv(id,txt){
                var app = document.getElementById("app")
                app.innerHTML += "<div>"+ id +": "+txt+ "</div>"
            }

        </script>
    </body>

</html>

小结

看到这里的同学都知道,博主就喜欢给大家留出优化空间,比如根据这个实现下csdn的私信功能,把页面拔下来都是现成的,对吧,所以都看到这里了,还不留个关注,点个赞吗,bye~

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-07-21 21:50:39  更:2022-07-21 21:50:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 22:37:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码