tp5.1+think-swoole搭建聊天

1.我使用的是linux系统,首先需要安装think-swoole

composer require topthink/think-swoole

2.在项目根目录config目录下修改swoole_server.php,没有自己新建。

<?php
// +----------------------------------------------------------------------
// | Swoole设置 php think swoole:server 命令行下有效
// +----------------------------------------------------------------------
return [
	'swoole_class'	=>	'app\index\controller\Swoole',
];

3.因为上面指向新的swoole.php ,所以我们去index模块新建Swoole.php.

 4.自己重写Swoole.php

<?php
namespace app\index\controller;
common下的是我自己的模型,因为下面用到了用不到的可以去掉
use app\common\model\ImFriend;
use app\common\model\ImMessage;
use app\common\model\User;
///模型结束
use think\swoole\Server;
use think\Db;
class Swoole extends Server
{
	protected $host = '';  你的域名
	protected $port = 9500;
    protected $type = 'socket';
    protected $serverType = 'ssl';
    protected $mode = SWOOLE_PROCESS;
    protected $sockType = SWOOLE_SOCK_TCP | SWOOLE_SSL;
	protected $option = [ 
		'worker_num'=> 4,
		'daemonize'	=> false,
		'backlog'	=> 128,
		'ssl_key_file' => '', ///key证书
        'ssl_cert_file' => '',cert证书
		'heartbeat_check_interval' => 10,
        'heartbeat_idle_time' => 300,
        'buffer_output_size' => 4*1024*1024, // 发送输出缓存区内存
        'socket_buffer_size' => 4*1024*1024, // 配置客户端连接的缓存区长度
	];
    //心跳检测:每60秒遍历所有连接,强制关闭10分钟内没有向服务器发送任何数据的连接
   
   
    // 事件回调定义
    public function onOpen($server, $request) {
        //将user_id 和fd 传到数据库 (后面将使用redis)
        $date=date('Y-m-d H:i',time());
         目前使用的是自增id,后面改成token
        $user_id=$request->get['user_id'];
        /*插入之前将所有的该userid状态改为0*/
        Db::table('im_user_status')->where('user_id',$user_id)->update(['status'=>0,'update_time'=>$date]);
        Db::table('im_user_status')->insert(['user_id'=>$user_id,'fd'=>$request->fd,'create_time'=>$date]);
        $res['type']='success';//发送信息
        $res['msg']='连接成功';//发送信息
        $server->push($request->fd, json_encode($res)); 
           echo "client {$request->fd} 打开\n";
    }

    public function onMessage($server, $frame) {
        $data=json_decode($frame->data);
        //内容
		switch ($data->type) {
			    case 'check':
			     $res['type']='success';//发送信息
				 $res['msg']='检测成功';//检测是否连接
				 $server->push($frame->fd, json_encode($res)); 
					break;
				case 'user':
				 $this->send($server,$frame,$data); //发送点对点消息
					break;
				case 'system':
				 $this->systemsend($server,$frame,$data); //发送系统消息
					break;
				default:
				 $res['msg']='默认';
			};
    }

    public function onRequest($request, $response) {
        var_dump('onrequest'.$request);
        $response->end("<h1>Hello Swoole. #" . rand(1000, 9999) . "</h1>");
    }

    public function onClose($ser, $fd) {
        Db::table('im_user_status')->where('fd',$fd)->where('status',1)->update(['status'=>0]);
        echo "client {$fd} closed为啥呢\n";
    }
	public function onReceive($server, $fd, $from_id, $data)
	{
	    echo "name {$data}";
		$server->send($fd, 'Swoole: '.$data);
	}
	//用户的信息发送
	public function send($server,$frame,$data){
	    $type=$data->msg->type;  //信息类型
	    $length=0; //录音长度
	    	switch ($type) {
			    case 'text':
			        $name='text';
			        $content=$data->msg->content->text;
					break;
				case 'img':
				    $name='url';
			        $content=$data->msg->content->url;
					break;
				case 'voice':
				    $name='url';
			        $content=$data->msg->content->url;
			        $length=$data->msg->content->length;
			        break;
				default:
			    $content=$data->msg->content->text;
			};
        //来源的id
        $fromid=$data->fromid;
        //要发送的id
        $toid=$data->toid;
        $username=$data->msg->userinfo->username;
        $avatar=$data->msg->userinfo->face;
        $date=date('Y-m-d H:i:s',time());
        //var_dump($frame);
        // var_dump($data);
        // echo "receive from {$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}\n";
        $a=ImFriend::where('user_id',$data->fromid)->where('friend_id',$data->toid)->find();
        //表示不是好友自动加
        if(empty($a)){
             $a=ImFriend::create(['user_id',$data->fromid,'friend_id',$data->toid]);
        }
        //将信息插入表中
        $id=ImMessage::create(['message_content'=>$content,'voice_length'=>$length,'type'=>$type,'from_user_id'=>$fromid,'from_user_name'=>$username,'from_user_avatar'=>$avatar,'to_user_id'=>$toid]);
        //查找朋友的fd
        $f=Db::table('im_user_status')->where('user_id',$toid)->where('status',1)->field('fd')->find();
         echo $f['fd'];
        if(!is_null($f)){
            /*表示查到了意味着在线*/
            $res['message']['sendmethod']='user';
            $res['message']['type']='user';
            $res['message']['fromid']=$fromid;
            $res['message']['msg']['type']=$type;
            $res['message']['msg']['content'][$name]=$content;
            $res['message']['msg']['content']['length']=$length;
            $res['message']['msg']['id']=$id->id;
            $res['message']['msg']['time']=$date;
            $res['message']['msg']['userinfo']['uid']=$fromid;
            $res['message']['msg']['userinfo']['username']=$username;
            $res['message']['msg']['userinfo']['face']=$avatar;
            $res['type']='getmessage';//发送信息
            $server->push($f['fd'], json_encode($res));
            echo "发送信息成功";
        }else {
            /*如果不在线则需要进行下一步操作如缓存消息*/
        }
        return ;
	}
	public function systemsend($server,$frame,$data)
	{
	    $type=$data->msg->type;  //信息类型
	    $length=0; //录音长度
	    	switch ($type) {
			    case 'text':
			        $name='text';
			        $content=$data->msg->content->text;
					break;
				case 'img':
				    $name='url';
			        $content=$data->msg->content->url;
					break;
				case 'voice':
				    $name='url';
			        $content=$data->msg->content->url;
			        $length=$data->msg->content->length;
			        break;
				default:
			    $content=$data->msg->content->text;
			};
        //来源的id
        $fromid=$data->fromid;
        //要发送的id
        $toid=$data->toid;
        $username=$data->msg->userinfo->username;
        $avatar=$data->msg->userinfo->face;
        $date=date('Y-m-d H:i:s',time());
        //将信息插入表中
        $id=ImMessage::create(['message_content'=>$content,'voice_length'=>$length,'type'=>$type,'from_user_id'=>$fromid,'to_user_id'=>$toid]);
            //根据id或者关键字查找答案
        $ids=$data->msg->content->content_id;
        $systemcontent=Db::table('im_system_content')->where('id',$ids)->find();
        $res['message']['sendmethod']='system';
        $res['message']['type']='system';
        $res['message']['fromid']=$fromid;
        $res['message']['toid']=$toid;
        $res['message']['msg']['type']=$type;
        $res['message']['msg']['content'][$name]=$systemcontent['content'];
        $res['message']['msg']['id']=$id->id;
        $res['message']['msg']['time']=$date;
        $res['message']['msg']['userinfo']['uid']=$toid;
        $res['type']='getmessage';//发送信息
        $server->push($frame->fd, json_encode($res)); 
        
        return ;
	    
	}
}
  

5.我们还需要一个测试端,我直接写在了php里,

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>websocket client</title>
</head>
<button type="button" id="send">发送</button>
<body>
<h1>swoole-ws测试</h1>
<script>
    var wsUrl = 'wss://aaa.xw.com:9500';
    var websocket = new WebSocket(wsUrl);

    websocket.onopen = function (evt) {
        console.log("ws client 连接成功!");
    };

    document.getElementById('send').onclick = function () {
        websocket.send('{"url":"index/index/websocket"}');
        console.log('ws client 发送数据');
    };

    websocket.onmessage = function (evt) {
        console.log("server return data: " + evt.data);
    };

    websocket.onclose = function (evt) {
        console.log("connect close");
    };

    websocket.onerror = function (evt, e) {
        console.log("error: " +JSON.stringify(evt));
    }
</script>
</body>

</html>

6.启动php服务 使用命令 

php think swoole:server

 

7.测试是否链接成功

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凉臣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值