微信小程序+php+swoole极速实现群聊

最近突然想做一个php实时通讯
我就点开了这个
WebSocket
我看了看官网的demo,觉得看起来很简单嘛,

<?php
//官网demo
$server = new swoole_websocket_server("0.0.0.0", 9501);
 
$server->on('open', function (swoole_websocket_server $server, $request) {
    echo "server: handshake success with fd{$request->fd}\n";//$request->fd 是客户端id
});
 
$server->on('message', function (swoole_websocket_server $server, $frame) {
    echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
    $server->push($frame->fd, "this is server");//$frame->fd 是客户端id,$frame->data是客户端发送的数据
    //服务端向客户端发送数据是用 $server->push( '客户端id' ,  '内容')
});
 
$server->on('close', function ($ser, $fd) {
    echo "client {$fd} closed\n";
});
 
$server->start();

我就是喜欢这种简单易懂的demo ,每行代码意思一看就明白、

接下来XML页面
 
<view>
  <view class="sendmessage">
    <input id="message" bindinput="inputMessage" placeholder="请输入聊天内容"></input>
    <button bindtap="sendMessage">发送</button>
  </view>
</view> 
<view>
<scroll-view scroll-y="true" class="history">
<view wx:for="{{message}}">
  <block wx:if="{{item.class == 1}}">
    <view class="user">{{item.name}}说:{{item.msg}}</view>
  </block>
 
  <block wx:else>
    <view class="service">{{item.name}}说:{{item.msg}}</view>
  </block>
</view>
</scroll-view>
</view> 

最后命令行运行php文件,之后浏览器打开html文件,F12打开调试界面看console,ok , 没有问题

这个时候我突然想到一个事情,因为我做多进程的那个教程里,在主进程中会将所有的子进程的句柄存起来,以后进行进程间通讯用。
那么 我将所有的客户端的链接存起来存成数组,每当一个客户端发送消息时,我就遍历这个客户端数组,将消息群发一遍,不久实现了聊天室了吗?
然后就,服务端代码成了这个样子

<?php
$map = array();//客户端集合
$server = new swoole_websocket_server("0.0.0.0", 9501);
 
$server->on('open', function (swoole_websocket_server $server, $request) {
    global $map;//客户端集合
    $map[$request->fd] = $request->fd;//首次连上时存起来
});
 
$server->on('message', function (swoole_websocket_server $server, $frame) {
    global $map;//客户端集合
    $data = $frame->data;
    foreach($map as $fd){
        $server->push($fd , $data);//循环广播
    }
});
 
$server->on('close', function ($ser, $fd) {
    echo "client {$fd} closed\n";
});
 
$server->start();

哈哈 , 我觉得这样就大功告成了,结果发现自己是 图样图森破大家可以自己试试,运行php后 , 浏览器打开两个页面,看看console.log的内容是什么

运行良好,可是并没有实现我们说的那种聊天效果。
找找原因吧。
我第一反映看看$map里面是什么,就输出看看,结果发现这个map里面只有一个元素。
唉,不对啊,我这是全局变量,难道不应该是有几个客户端链接,就有几个元素吗?
这是怎么回事啊,竟然没有保存到所有客户端id?

到了这一步,我解决不了map变量的这个问题了,然后我就想看看那个fd是什么东西,
老规矩 var_dump输出 , 发现fd就是 int类型的数字,并且是自增的
这好办了,不就是数字嘛

于是呼,我就这样做
变量存不了,我搞不定,我存文本里嘛。
最终版 websocket.php

<?php
 
$server = new swoole_websocket_server("0.0.0.0", 9501);
 
$server->on('open', function (swoole_websocket_server $server, $request) {
    file_put_contents( __DIR__ .'/log.txt' , $request->fd);
});
 
$server->on('message', function (swoole_websocket_server $server, $frame) {
    global $client;
    $data = $frame->data;
    $fd=$frame->fd;
    $m = file_get_contents( __DIR__ .'/log.txt');
    for ($i=1 ; $i<= $m ; $i++) {
        echo PHP_EOL . '  i is  ' . $i .  '  data  is '.$data  . '  m = ' . $m;
    if($i->$fd){
        $arr=json_decode($data,true);
        $arr['
name
']="我";
        $arr['class']=1;
        $data=json_endode($arr);
 
    }    
    $server->push($i, $data );
    }
 
});
 
$server->on('close', function ($ser, $fd) {
    echo "client {$fd} closed\n";
});
 
$server->start();
 

最最重要的是我们的小程序客户端的js代码
socket.js 


 
//获取应用实例
var app = getApp()
var socketOpen="false"
var inputMessage=""
var i=0
var msgInfo={}
Page({
    data: {
        message:""
  },
 
    //获取输入框信息
    inputMessage: function(e) {
        inputMessage=e.detail.value
    },
    
    //点击事件
    sendMessage:function(){
        if (socketOpen) {
            var nickname = wx.getStorageSync('nickname')
            if (nickname=="") {
                nickname="游客"
            }        
         var data1='{"name":"'+nickname+'","msg":"'+inputMessage+'"}'
            wx.sendSocketMessage({
                data:data1
            })
        }
    },
 
  //页面加载事件
  onLoad: function () {
      var that=this
    wx.connectSocket({
        url: 'ws://192.168.1.181:9502/swoole/ws_server.php'
    })
 
    wx.onSocketOpen(function(res) {
        socketOpen="true"
        
    })
 
    wx.onSocketMessage(function(res) {
        i=i+1
        //console.log(res)
        var re=JSON.parse(res.data)
        msgInfo[i]=re
        console.log(msgInfo)
        if(res.data){
            that.setData({
                message:msgInfo
            })
        }       
       
    })
  }
})
 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
环境要求 PHP >= 7.0 PHP fileinfo 拓展 储存文件需要用到 PHP gd 拓展 控制台显示二维码 PHP posix 拓展 控制台显示二维码(linux) PHP 系统命令 拓展 执行clear命令 PHP SimpleXML 拓展 解析XML 安装 请确保已经会使用composer! 运行微信账号的语言设置务必设置为简体中文!!否则可能出现未知的错误! 1、git git clone https://github.com/HanSon/vbot.git cd vbot composer install 2、composer composer require hanson/vbot 运行 正常运行 php example/index.php 带session运行 php example/index.php --session yoursession 关于session : 带session运行会自动寻找设定session指定的cookies,如不存在则新建一个文件夹位于 /tmp/session 中,当下次修改代码时再执行就会免扫码自动登录。 如果不设置,vbot会自动设置一个6位的字符的session值,下次登录也可以直接设定此值进行面扫码登录。 PS:运行后二维码将保存于设置的缓存目录,命名为qr.png,控制台也会显示二维码,扫描即可(linux用户请确保已经打开ANSI COLOR) 警告!执行前请先查看index.php的代码,注释掉你认为不需要的代码,避免对其他人好友造成困扰 请在terminal运行!请在terminal运行!请在terminal运行! 目录结构 vbot demo (vbot 当前在运行的代码,也欢迎大家提供自己的一些实战例子) example (较为初级的实例) src (源码) tmp (假设缓存目录设置在此) session hanson (设定值 php index.php --session hanson) 523eb1 (随机值) users 23534234345 (微信账号的UIN值) file (文件) gif (表情) jpg (图片) mp3 (语音) mp4 (视频) contact.json (联系人 debug模式下存在) group.json (群组 debug模式下存在) member.json (所有群的所有成员 debug模式下存在) official.json (公众号 debug模式下存在) special.json (特殊账号 debug模式下存在) message.json (消息) 体验 扫码后,验证输入“echo”即可自动加为好友并且拉入vbot群。 vbot并非24小时执行,有时会因为开发调试等原因暂停功能。如果碰巧遇到关闭情况,可加Q群 492548647 了解开放时间。执行后发送“拉我”即可自动邀请进群。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值