Nonconformist Propaganda Machine

    ssocket
    TypeScript icon, indicating that this package has built-in type declarations

    2.1.14 • Public • Published

    npm version

    仿 Koa 中间件控制的 WebSocket 服务,食用简单,上手容易, 支持 GZIP 解压缩和 ProtoBuffer 解压缩配置,觉得小弟写的还行的话,就给个Star⭐️吧~

    使用说明

    点击安装客户端程序

    运行方式

    脚本示例

    mkdir socket_test
    cd socket_test
    npm init --yes
    npm i -s ssocket 
    vim app.js
    # 输入此内容
    // TS 引入方式 import Ssocket from "ssocket"
    const Ssocket = require("ssocket").default;
    const server = new Ssocket({ 
        port: 8080
    });
    server.on("start-up", function(){
        console.log("启动成功")
    })
    
    # 然后执行
    # Node 安装自动百度
    node app.js
    // 控制台打印 启动成功
    

    其他配置

    const http = require("http")
    const Ssocket = require("ssocket").default;
    const httpServer = http.createServer()
    const server = new Ssocket({
        server: httpServer,
        verifyClient: ({ origin, secure, req }, callback) => {
            callback(true/**返回 false 的话,连接就会中断并给前端返回 403 的HTTP错误码 */)
        }, // 非必传
        perMessageDeflate: true, // 非必传
        maxPayload: 1024 * 1024 * 10, // 最大传输单位 10M // 非必传
        adapter:{// 非必传, 用于服务集群做消息同步
            // MQ 交换机名称前缀
            key:"SocketTipKey",
            redis:{ 
                prefix: 'im',
                host: '127.0.0.1',
                port: '6379',
                expire: 60,
            },
            mqurl:"amqp://username:password@IP"
        }
    })
    
    httpServer.listen(8080, function(){
        console.log("启动成功")
    })

    ProtoBuffer 解压缩配置

    const server = new Ssocket({
        /**protos 开启压缩并配置:注 当数据量大于 128 字节的时候自动开启 GZIP 压缩  */
        protos:{ // 非必传
            // 配置请求编码
            request:{
                "test":{
                    /**
                     * [required单字段|repeated重复字段|message自定义结构] [string|uint[8|16|32]|float|double] fieldname: 序号同级唯一
                     */
                    "required string username": 0,
                }
            },
            // 配置响应编码
            response:{
                "test":{
                    /**
                     * [required单字段|repeated重复字段|message自定义结构] [string|uint[8|16|32]|float|double] fieldname: 序号同级唯一
                     */
                    "required string username": 0,
                    "required uint8 age": 1,
                    "required uint32 amount": 2,
                    "required string avatar": 3,
                    "required Data test": 4,
                    "message Data": {
                        "required string usernmae": 0,
                        "repeated List list": 1,
                        "message List": {
                            "required uint32 id": 0,
                        },
                    },
                }
            }
        }
    })
    
    server.router.ONPath("test", function(ctx, next){
        console.log(ctx.data)// {
        //     username:"测试账号",
        // }
        return {
            username: `登录成功,欢迎${ctx.data.usernmae}`
        }
    })
    
    // 前端
    client.request("test", {
        username:"测试账号",
    }, function(ctx){
        console.log("返回状态", ctx.status)// 200
        console.log("返回说明", ctx.msg)// ok
        console.log("返回数据", ctx.data) // { username:"登录成功,欢迎测试账号" }
    })

    服务端对象事件控制

    server.on("connection", function(client/**SWebSocket */, request/**IncomingMessage */){
        console.lof("接收到一个客户端连接", client.getid())  
    })
    server.on("reconnection", function(client/**SWebSocket */, id/**client_id*/){
        console.lof("一个客户端重连成功", client.getid())  
    })
    server.on("route-error", function(ctx, err){ 
        console.log("路由报错", ctx, err) 
    })
    server.on("close", function(client_id, code, reason){ 
        console.log("连接关闭", client_id, code, reason) 
    })

    路由事件控制

    const Ssocket = require("ssocket").default;
    const { Router, Code, CODE } = require("ssocket");
    const server = new Ssocket({ port:8080 })
    
    // 扩展错误码
    Code.expandStatusCode(201, "没有提交【username】字段")
    // 创建路由对象
    const main = new Router();
    const user = new Router();
    const login = new Router();
    // 事件中间件拦截校验请求参数
    login.USEMiddleware(function(ctx, next){
        // 校验失败返回错误码
        if(!ctx.data.username) return CODE[201];
        // 校验成功,注:所有的中间件必须拥有返回值,没有返回值就返回 next()
        return next();
    })
    // 在 /login 路径下注册一个请求处理方法
    login.ONPath("/login", function(ctx, next){
        return {
            username: `登录成功,欢迎${ctx.data.usernmae}`
        }
    })
    // 将登陆路由注册到 /user 路由下
    user.USEPathMiddleware("/user", login.routes)
    main.USEPathMiddleware("user", user.routes);
    
    // 将 main 路由对象注册到 Socket 服务中
    server.router.USEMiddleware(main.routes);
    
    // 前端
    client.request("user/user/login"/*由上面路由对象会组成这个路由路径*/, { username:"小明" }, function(ctx){
        console.log("返回状态", ctx.status)// 200/201
        console.log("返回说明", ctx.msg)// ok/没有提交【username】字段
        console.log("返回数据", ctx.data) // { username:"登录成功,欢迎小明" }
    })

    消息控制

    login.ONPath("/login", async function(ctx, next){
    
        ctx.socket // 在上下文中会注入 SWebSocket 对象
        ctx.app // 在上下文中会注入 Application 对象,这个对象等于上面的 Ssocket
        // 加入房间
        ctx.app.join(ctx.socket_id, "roomid_123")
        //离开房间
        ctx.app.leave(ctx.socket_id, "roomid_123")
    
        // 获取所有的房间ID
        let rooms = await ctx.app.getRoomall()
        // 根据 客户端ID 获取所在的所有房间ID
        let rooms = await ctx.app.getRoomidByid(ctx.socket_id)
        // 根据房间号获取所有的客户端ID
        let clientids = await ctx.app.getClientidByroom("roomid_123")
        // 获取所有的房间总数
        let room_count = await ctx.app.getAllRoomcount()
        // 获取房间内人员数量
        let client_count = await ctx.app.getRoomsize("roomid_123")
        // 判断客户端是否存在啊某个房间
        let flog = await ctx.app.hasRoom(ctx.socket_id, "roomid_123")
    
        // 单独向某条连接发送消息
        ctx.app.sendSocketMessage(ctx.socket_id, "user.user.login", { username:`登录成功,欢迎${ctx.data.usernmae}` })
        // 单独向某个房间发送消息
        ctx.app.sendRoomMessage("roomid_123", "user.user.login", { username:`登录成功,欢迎${ctx.data.usernmae}` })
        // 向所有连接发送广播消息
        ctx.app.sendBroadcast("user.user.login", { username:`登录成功,欢迎${ctx.data.usernmae}` })
    
        return {
            username: `登录成功,欢迎${ctx.data.usernmae}`
        }
    })
    
    
    // 前端
    client.on("user.user.login", function(ctx){
        console.log("返回状态", ctx.status)// 200
        console.log("返回说明", ctx.msg)// ok
        console.log("返回数据", ctx.data) // { username:"登录成功,欢迎小明" }
    })

    客户端对象事件控制

    server.on("connection", function(client/**SWebSocket */, request/**IncomingMessage */){
        console.log("接收到一个客户端连接", client.getid())
    
        client.on("close", function(id, code, reason){
            console.log("连接断开, 客户端ID", id)
            console.log("断开代码", code)
            console.log("断开原因", reason)
        })
        client.on("shakehands", function(status){
            console.log("握手状态", status)// 2握手成功|3握手完毕
        })
        client.on("connection", function(id){
            console.log("握手完毕,连接成功, 客户端ID", id)
        })
        client.on("reconnection", function(id){
            console.log("重新连接成功, 客户端ID", id)
        })
        client.on("ping", function(client_now_time){
            console.log("收到客户端一个心跳事件, 此时该客户端当前时间是", client_now_time)
        })
        client.on("pong", function(){
            console.log("服务器回复一个心跳响应事件")
        })
    
    })

    Install

    npm i ssocket

    DownloadsWeekly Downloads

    0

    Version

    2.1.14

    License

    ISC

    Unpacked Size

    87.5 kB

    Total Files

    19

    Last publish

    Collaborators

    • summer.li