美文网首页
从一个聊天室Demo研究即时通讯

从一个聊天室Demo研究即时通讯

作者: 飞鱼ll | 来源:发表于2017-08-26 22:59 被阅读102次

    传输协议 websocket 传输格式 json
    具体业务根据json传输的内容来实现。

    1.先从最直观的页面入口开始分析

    先启动项目

    屏幕快照 2017-08-26 下午10.22.36.png

    打开页面

    屏幕快照 2017-08-26 下午10.24.58.png

    打开项目源文件,找到对应的入口文件

    屏幕快照 2017-08-26 下午10.28.10.png

    分析接口:
    连接服务器:

    ws://127.0.0.1:7272
    

    登陆:(用户名:222,聊天室ID:1)

    {"type":"login","client_name":"222","room_id":"1"}  返回数据:{"type":"login","client_id":xxx,"client_name":"xxx","client_list":"[...]","time":"xxx"}
    

    发送消息:(to_client_id发送给谁,all表示聊天室所有人,content消息内容)

    {"type":"say","to_client_id":"all","to_client_name":"","content":"66666"}
    

    接收消息:

    {"type":"say","from_client_id":xxx,"to_client_id":"all/client_id","content":"xxx","time":"xxx"}
    

    退出:

    {"type":"logout","client_id":xxx,"time":"xxx"}
    

    测试(Advanced REST client):

    屏幕快照 2017-08-26 下午10.46.45.png

    服务器地址:http://www.chaisz.xyz/webchat
    socket接口:ws://www.chaisz.xyz:7272

    一切OK,接下来准备研究一下iOS

    ios项目地址:https://github.com/chaishuanzhu/xchat-ios

    服务端代码

    <?php
    
    // set_time_limit(0);
    
    // sleep(5);
    
    // 这里是我们上面得到的deviceToken,直接复制过来(记得去掉空格)
    $deviceToken = 'ed8c1c155a6daf448f610ae749eec794be551f8d1b145448711eea973583f820';
    
    
    // Put your private key's passphrase here:
    $passphrase = '123456';
    
    
    // Put your alert message here:
    $message = 'My first push test!';
    
    
    ////////////////////////////////////////////////////////////////////////////////
    
    
    $ctx = stream_context_create();
    
    stream_context_set_option($ctx, 'ssl', 'allow_self_signed', true);
    
    stream_context_set_option($ctx, 'ssl', 'verify_peer', false);
    
    stream_context_set_option($ctx, 'ssl', 'local_cert', '/Applications/MAMP/htdocs/Push-dev/ck.pem');
    
    stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
    
    
    // Open a connection to the APNS server
    
    //这个为正是的发布地址
    
     // $fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
    
    //这个是沙盒测试地址,发布到appstore后记得修改哦
    
     $fp = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err,$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
    
    //$fp=stream_socket_client("udp://127.0.0.1:1113", $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
    
    if (!$fp)
    
    exit("Failed to connect: $err $errstr" . PHP_EOL);
    
    
    echo 'Connected to APNS' . PHP_EOL;
    
    
    // Create the payload body
    
    $body['aps'] = array(
    
    'alert' => $message,
    
    'sound' => 'default'
    
    );
    
    
    // Encode the payload as JSON
    
    $payload = json_encode($body);
    
    
    // Build the binary notification
    
    $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
    
    
    // Send it to the server
    
    $result = fwrite($fp, $msg, strlen($msg));
    
    
    if (!$result)
    
    echo 'Message not delivered' . PHP_EOL;
    
    else
    
    echo 'Message successfully delivered' . PHP_EOL;
    
    
    // Close the connection to the server
    
    fclose($fp);
    
    ?>
    

    ios端代码

    #import "AppDelegate.h"
    #import <UserNotifications/UserNotifications.h>
    
    @interface AppDelegate ()<UNUserNotificationCenterDelegate>
    
    @end
    
    @implementation AppDelegate
    
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
        
        // 注册
        UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
        [center requestAuthorizationWithOptions:UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionCarPlay completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (!error) {  
                [[UIApplication sharedApplication]registerForRemoteNotifications];
            }
        }];
        center.delegate = self;
        return YES;
    }
    
    
    - (void)applicationWillTerminate:(UIApplication *)application {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
    
    
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
        // 把此处输出的 “deviceToken” 去掉空格 配置到 php 代码中,就可以向这台设备发送通知了。
        NSLog(@"regisger success:%@", deviceToken);
    }
    
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(nonnull NSError *)error{
        
        NSLog(@"%@",error);
    }
    
    @end
    

    测试结果:

    屏幕快照 2017-09-10 下午11.55.33.png

    未完待续!

    GetWayworker与ThinkPHP结合使用做一个聊天应用后台。

    1. 创建项目

    在命令行下面,切换到你的web根目录下面并执行下面的命令:

    composer create-project topthink/think xchat  --prefer-dist
    
    屏幕快照 2017-09-13 下午11.23.59.png

    到应用根目录安装GetWayworker

    composer require workerman/gateway-worker
    
    屏幕快照 2017-09-13 下午11.29.24.png

    安装GatewayClient

    composer require workerman/gatewayclient
    
    屏幕快照 2017-09-13 下午11.32.06.png

    然后下载一个聊天室Demo:http://www.workerman.net/workerman-chat

    把里面的文件放到应用中。完成后的项目目录如下。

    屏幕快照 2017-09-13 下午11.40.32.png 屏幕快照 2017-09-13 下午11.42.01.png

    修改start.php

    屏幕快照 2017-09-13 下午11.46.16.png

    修改Events.php (参考:http://doc2.workerman.net/326107)

    屏幕快照 2017-09-13 下午11.47.43.png

    启动应用

    php start.php start
    
    屏幕快照 2017-09-13 下午11.51.12.png

    测试链接:

    屏幕快照 2017-09-13 下午11.55.04.png

    新建bind.php控制器测试:

    <?php
    namespace app\index\controller;
    //加载GatewayClient。安装GatewayClient参见本页面底部介绍
    require_once ROOT_PATH.'vendor/workerman/gatewayclient/Gateway.php';
    // GatewayClient 3.0.0版本开始要使用命名空间
    use GatewayClient\Gateway;
    // 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值
    class Bind
    {
    
      public function index() {
        echo '66666';
      }
        public function bind () {
    
            Gateway::$registerAddress = '127.0.0.1:1236';
    
            // 假设用户已经登录,用户uid和群组id在session中
            $uid      = '123456';
            $group_id = '1';
            $client_id = '7f00000108fe00000001';
            // client_id与uid绑定
            Gateway::bindUid($client_id, $uid);
            // 加入某个群组(可调用多次加入多个群组)
            Gateway::joinGroup($client_id, $group_id);
        }
    
        public function send_message($uid = '123456', $message = '25652652', $group = '1') {
            // //加载GatewayClient。安装GatewayClient参见本页面底部介绍
            // require_once '/your/path/GatewayClient/Gateway.php';
            // // GatewayClient 3.0.0版本开始要使用命名空间
            // use GatewayClient\Gateway;
            // 设置GatewayWorker服务的Register服务ip和端口,请根据实际情况改成实际值
            Gateway::$registerAddress = '127.0.0.1:1236';
    
            // 向任意uid的网站页面发送数据
            Gateway::sendToUid($uid, $message);
            // 向任意群组的网站页面发送数据
            Gateway::sendToGroup($group, $message);
    
            $this -> post('http://www.chaisz.xyz/xchat/index.php/push/push/ios',array('msg' => '54131321'));
        }
    
        function post($url, $post_data){
              //初始化
              $curl = curl_init();
              //设置抓取的url
              curl_setopt($curl, CURLOPT_URL, $url);
              //设置头文件的信息作为数据流输出
              curl_setopt($curl, CURLOPT_HEADER, 1);
              //设置获取的信息以文件流的形式返回,而不是直接输出。
              curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
              //设置post方式提交
              curl_setopt($curl, CURLOPT_POST, 1);
              //设置post数据
              curl_setopt($curl, CURLOPT_POSTFIELDS, $post_data);
              //执行命令
              $data = curl_exec($curl);
              //关闭URL请求
              curl_close($curl);
              //显示获得的数据
              // print_r($data);
        }
    }
    
    
    屏幕快照 2017-09-13 下午11.57.41.png

    测试:

    1. http://xchat.chaisz.xyz/index/bind/bind 这一步要把用户id和socket连接建立时生成的client_id传到服务器进行绑定。同时根据uid查找用户加入的群组。

      接口地址: http://xchat.chaisz.xyz/index/bind/bind
      返回格式: json
      请求方式: http/https post
      请求参数说明:
      名称 类型 必填 说明
      uid string 用户ID
      client_id string socket连接返回的ID
      返回参数说明:
      名称 类型 说明
      参考JSON返回示例 - -
      参考JSON返回示例 :
      {"code": 200,"message": "success!"}
    2. http://xchat.chaisz.xyz/index/bind/send_message 向用户发送消息

    屏幕快照 2017-09-14 上午12.01.02.png IMG_0208.PNG

    相关文章

      网友评论

          本文标题:从一个聊天室Demo研究即时通讯

          本文链接:https://www.haomeiwen.com/subject/rkbvdxtx.html