• 技术文章 >微信小程序 >小程序开发

    node.js来实现微信小程序实时聊天功能(附代码)

    不言不言2018-08-15 09:37:05原创5903
    本篇文章给大家带来的内容是关于如何使用node.js来实现微信小程序实时聊天功能(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

    我对IM这块可谓是真正的小白,所以没接触过的可以来参考参考。
    在微信这个聊天工具里的小程序上实现聊天功能,总感觉怪怪的。但领导要求了,总是要干的。

    然后就实时通讯这个关键词展开搜索,穿梭于网页之间。不过粘贴复制的真的太多了,找了半天也没找到想要的,不过还是提取到了关键词WebSocket和node.js,然后搜索这两是啥,什么关系,总算明白了一点。

    最后确定了第一步需要干的是用的node.js搭建服务(我是装在自己的窗口下的):

    1.首先到官网下载node.js,连接:https:
    //nodejs.org/en/安装很简单,双击下载好的文件,直接下一步一步,没什么特殊的选择,路径默认就好
    可以打开命令行窗口输入节点-v会输出版本,来检验是否安装成功,其实这个也没什么必要

    2.然后新建一个文件夹(我的node.js是安装在?盘的,然后再d盘下新建了个叫网页套接字的文件夹)
    然后用命令转到该目录下: 在这个文件下安装我们要使用的模块: 安装模块前需要先生成一个配置文件,不然会报错(反正我报了)

    生成配置文件命令:npm init -f
    执行后可以看到在该文件下多了一个叫package.json的配置文件,先不用管(后面也没管过),接下来继续安装模块的操作
    刚开始我是安装的socket.io,后来发现小程序根本用不了,所以这里也不说socket.io了。我们这里用ws
    安装ws命令:npm install --save ws(卸载模块命令:npm uninstall模块名字)

    3.安装好模块后,在你目录下创建一个的.js文件,我这是一个ws.js 我这里肯定会比你们的文件要多,不用这个在意然后打开这个的.js文件,开始编辑你的服务端代码,这个随便你用记事本还是其他什么软件这是最简单基础的一个打开连接,响应的代码:

    //引入ws模块
    const WebSocket = require('ws');
    //创建服务 port是端口
    const wss = new WebSocket.Server({ port: 80});
    //客户端连接时会进这个
    wss.on('connection', function connection(ws) {
        console.log('连接成功');
        //客户端发送消息时会触发这个
        ws.on('message', function incoming(data) {
            console.log('收到消息');
            //data是客户端发送的消息,这里clients.foreach是广播给所有客户端
            wss.clients.forEach(function each(client) {
                //把客户端发来的data,循环发给每个客户端
                client.send(data);
            });
        });
    });

    这里贴上稍微比较完善的代码,这里是用数据库保存的发送的消息,用的mysql,所以需要在安装mysql模块
    npm install --save mysql
    代码:
    这里有很多注释的代码,都是我研究时用到的,无视可以删掉或
    这个MySQL的的数据连接需要根据自己的修改,也是表
    我这用到的表就两个字段ID,味精

    var http=require('http');
    var qs = require('querystring'); //
    var ws=require('ws');
    
    var server=http.createServer(function (req, res) {
        res.end("This is a WebSockets server!");
    });
    var url = require('url');
    //验证函数
    function ClientVerify(info) {
        var ret = false;//拒绝
        //url参数
        var params = url.parse(info.req.url, true).query;
        //console.log(groupid);
        //groupid=params['groupid']
        //谁谁谁来到了讨论组
        // wss.clients.forEach(function each(client) {
        //     client.send('233');
        // });
        return true;
    
    }
    var wss = new ws.Server( { server: server,verifyClient: ClientVerify } );
    
    /*//引入数据库
     var mysql = require('mysql');
     //连接数据库信息 普通版
     var connection = mysql.createConnection({
        host  : '58.87.94.16',
        user  : 'root',
        password : 'root',
        database : 'bootdo'
    });*/
    //引入数据库
    var mysql = require('mysql');
    // 创建数据池
    const pool  = mysql.createPool({
        host     : '58.87.94.16',   // 数据库地址
        user     : 'root',    // 数据库用户
        password : 'root',   // 数据库密码
        database : 'bootdo'  // 选中数据库
    })
    /*接收一个sql语句 以及所需的values
    这里接收第二参数values的原因是可以使用mysql的占位符 '?'
    比如 query(`select * from my_database where id = ?`, [1])
    好像可以直接使用pool.query,暂时不明*/
    let query = function(sql,values,callback){
        pool.getConnection(function(err,conn){
            if(err){
                callback(err,null,null);
            }else{
    
                conn.query(sql,values,function(err,results,fields){
                    //释放连接
                    conn.release();
                    //事件驱动回调
                    callback(err,results,fields);
                });
            }
        });
    };
    module.exports=query;
    
    wss.on('connection', function connection(ws) {
        console.log('链接成功!');
        //console.log(ws);
        //查询历史聊天记录 广播给连接的客户端
        var sql='select * from hi_test where groupid=1';
        console.log('sql语句',sql);
        query(sql,function (err,res,fields) {
            console.log('sql操作返回:', res);
            if(res!=null){
                ws.send(JSON.stringify(res));
            }
        });
        //监听客户端发送得消息
        ws.on('message', function incoming(data) {
            console.log('来自客户端得message:',data);
            //保存客户端发送得消息到数据库
            sql="insert into hi_test(msg) values(?)";
            console.log('sql语句',sql);
            query(sql,data,function (err,res,fields) {
                console.log('sql操作返回:',res);//res.insertId
            });
            var sendData=JSON.stringify([{msg:data}])
            /**
             * 把消息发送到所有的客户端
             * wss.clients获取所有链接的客户端
             */
            wss.clients.forEach(function each(client) {
                client.send(sendData);
            });
        });
    });
    
    server.listen(80, function listening() {
        console.log('服务器启动成功!');
    });
    
    
    
    /*发起get请求
    var options = {
        hostname: 'www.tjjxsoft.cn',
        path: '/attendanceParameter/getAttendanceParameter/13',
        method: 'GET'
    };
    
    var req = http.request(options, function (res) {
        console.log('状态: ' + res.statusCode);
        res.on('data', function (chunk) {
            console.log('返回数据: ' + chunk);
        });
    });
    
    req.on('error', function (e) {
        console.log('problem with request: ' + e.message);
    });
    
    req.end();*/
    
    /*
    /!*构建http服务*!/
    var app = require('http').createServer()
    /!*引入socket.io*!/
    var io = require('socket.io')(app);
    /!*定义监听端口,可以自定义,端口不要被占用*!/
    var PORT = 80;
    /!*监听端口*!/
    app.listen(PORT);
    
    /!*定义用户数组*!/
    var users = [];
    /!**
     *监听客户端连接
     *io是我们定义的服务端的socket
     *回调函数里面的socket是本次连接的客户端socket
     *io与socket是一对多的关系
     *!/
    io.on('connection', function (socket) {
        /!*所有的监听on,与发送emit都得写在连接里面,包括断开连接*!/
        socket.on('login',function(data){
            console.log('有人登录了:')
            console.log(data);
            users.push({
                username:data.username
            });
            /!*向所有连接的客户端广播add事件*!/
            io.sockets.emit('add',data)
        })
    })
    console.log('app listen at'+PORT);*/

    然后命令行输入节点ws.js(你自己的文件名)回车,就已经启动了服务

    4.现在服务就已经起来了,弄接下来小程序这边的
    直接贴代码:

    wxml:

    <view class='homeView'>
        <scroll-view scroll-y style="height:500px;" scroll-top='{{scrolltop}}'>
            <view class='listView'>
                <block wx:for="{{serverMsg}}" wx:key='*this'>
                    <!--  -->
                    <view wx:if="{{item.user.id!=userInfo.userId}}" class='leftView'>
                        <view class='name'>{{item.user.name}}</view>
                        <view class='imgmsgleft'>
                            <view>
                            <!-- 我这用的是自己另一个服务的图片 -->
                                <image class='touimg' src='https://www.tjjxsoft.cn/static/images/img005.png'></image>
                            </view>
                            <view>{{item.msg}}</view>
                        </view>
                    </view>
                    <view  wx:else class='rightView'>
                        <view class='name'>{{item.user.name}}</view>
                        <view class='imgmsg'>
                            <view>{{item.msg}}</view>
                            <view>
                            <!-- 我这用的是自己另一个服务的图片 -->
                                <image class='touimg' src='https://www.tjjxsoft.cn/static/images/img005.png'></image>
                            </view>
                        </view>
                    </view>
                </block>
            </view>
        </scroll-view>
        <view class='sendView'>
            <input bindinput='sendTextBind' placeholder="输入聊天内容" value='{{sendText}}' />
            <button bindtap='sendBtn' type="primary">发送</button>
        </view>
    </view>

    .js文件:

    var app = getApp();
    Page({
        data: {
            socket_open: false,//判断连接是否打开
            sendText: "",//发送的消息
            serverMsg: [],//接受的服务端的消息
            userInfo: { userId: 1, name: "呵呵",img:'头像'},//app.appData.userInfo,
            scrolltop: 999
        },
    
        /**输入内容 */
        sendTextBind: function(e) {
            this.setData({
                sendText: e.detail.value
            });
            console.log(this.data.sendText);
        },
        /**发送消息 */
        sendBtn: function(e) {
            console.log('发送消息事件!');
            var msgJson = {
                user: {
                    id: this.data.userInfo.userId,//app.appData.userInfo.userId, //唯一ID区分身份
                    name: this.data.userInfo.name, //显示用姓名
                    img: this.data.userInfo.img, //显示用头像
                },
                msg: this.data.sendText,//发送的消息
                groupid:1
            }
            //发送消息
            this.send_socket_message(JSON.stringify(msgJson));
            this.setData({
                sendText: ""//发送消息后,清空文本框
            });
        },
        onLoad: function(options) {
            // app.login();
            // this.setData({
            //     userInfo: app.appData.userInfo
            // });
            //初始化
            this.wssInit();
        },
        wssInit() {
            var that = this;
            //建立连接
            wx.connectSocket({
                url: 'ws://localhost'//app.appData.socket
            })
            //监听WebSocket连接打开事件。
            wx.onSocketOpen(function(res) {
                console.log('WebSocket连接已打开!');
                that.setData({
                    socket_open: true
                });
            });
            //监听WebSocket接受到服务器的消息事件。
            wx.onSocketMessage(function(res) {
                console.log('收到服务器内容:', res);
                var server_msg = JSON.parse(res.data);
                console.log(server_msg);
                if (server_msg != null) {
                    var msgnew = [];
                    for (var i = 0; i < server_msg.length; i++) {
                        msgnew.push(JSON.parse(server_msg[i].msg));
                    }
                    msgnew=that.data.serverMsg.concat(msgnew);
                    that.setData({
                        serverMsg: msgnew,
                        scrolltop: msgnew.length * 100
                    });
                    console.log(that.data.serverMsg);
                }
            });
            //监听WebSocket错误。
            wx.onSocketError(function(res) {
                console.log('WebSocket连接打开失败,请检查!', res)
            });
    
        },
        send_socket_message: function(msg) {
            //socket_open,连接打开的回调后才会为true,然后才能发送消息
            if (this.data.socket_open) {
                wx.sendSocketMessage({
                    data: msg
                })
            }
        }
    })

    wxss:

    .homeView {
        border-top: 1px solid #ededed;
    }
    .listView{
        padding-bottom: 50px;
    }
    .listView>view {
        padding: 10px;
    }
    
    .rightView {
        text-align: right;
    }
    
    .imgmsgleft {
        display: flex;
        justify-content: flex-start;
        align-items: center;
    }
    
    .imgmsgleft>view:last-child {
        border: solid 1px gray;
        padding: 10px;
        border-radius: 6px;
    }
    
    .imgmsg {
        display: flex;
        justify-content: flex-end;
        align-items: center;
    }
    
    .imgmsg>view:first-child {
        border: solid 1px gray;
        padding: 10px;
        border-radius: 6px;
        background-color: green;
    }
    
    .touimg {
        width: 50px;
        height: 50px;
    }
    
    .name {
        font-size: 14px;
        color: gray;
    }
    
    .sendView {
        display: flex;
        width: 100%;
        position: fixed;
        bottom: 0px;
        border-top: 1px #ededed solid;
        background-color: white;
    }
    
    .sendView>button {
        width: 20%;
    }
    
    .sendView>input {
        width: 80%;
        height: auto;
    }

    预览的时候一定要打开调试,因为这不是wss协议,是没法直接用的

    相关推荐:

    使用CSS3仿微信聊天小气泡的实例介绍

    使用图灵api创建微信聊天机器人,api聊天机器人_PHP教程

    实现微信UI的聊天功能

    以上就是node.js来实现微信小程序实时聊天功能(附代码)的详细内容,更多请关注php中文网其它相关文章!

    声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。
    专题推荐:node.js
    上一篇:微信小程序支付的流程问题解析(代码解析) 下一篇:小程序进行跳转页面所需的五种方法
    Web大前端开发直播班

    相关文章推荐

    • 归纳整理微信小程序常用表单组件• 浅析小程序中如何优雅地进行模块化处理?• 记录一次实践,看看小程序购物车动画怎么优化• 浅谈小程序确保每个页面都已登陆的方法• 小程序中怎么对网络请求进行二次封装
    1/1

    PHP中文网