美文网首页
从一个聊天室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