socket之webmsgsender使用方法

web-msg-sender是一款web长连接推送框架,采用PHPSocket.IO开发,基于WebSocket长连接通讯,如果浏览器不支持WebSocket则自动转用comet推送。 通过后台推送消息,消息可以即时推送到客户端,非轮询,实时性非常好,性能很高。

特点:

  • 多浏览器支持
  • 支持针对单个用户推送消息
  • 支持向所有用户推送消息
  • 长连接推送(websocket或者comet),消息即时到达
  • 支持在线用户数实时统计展示
  • 支持在线页面数实时统计展示
  • 支持跨域推

基本使用方法

下载 并解压缩到任意目录

linux系统cd到到框架目录里运行php start.php start -d 

关闭 php start.php stop 重启 php start.php restart -d 

前端使用

<script src='http://cdn.bootcss.com/socket.io/1.3.7/socket.io.js'></script>
<script>
    // 连接服务端,workerman.net:2120换成实际部署web-msg-sender服务的域名或者ip
    var socket = io('http://workerman.net:2120');
    // uid可以是自己网站的用户id,以便针对uid推送以及统计在线人数
    uid = 123;
    // socket连接后以uid登录
    socket.on('connect', function(){
    	socket.emit('login', uid);
    });
    // 后端推送来消息时
    socket.on('new_msg', function(msg){
        console.log("收到消息:"+msg);
    });
    // 后端推送来消息时
    socket.on('kline', function(msg){
        console.log("收到消息:"+msg);
    });
    // 后端推送来在线数据时
    socket.on('update_online_count', function(online_stat){
        console.log(online_stat);
    });
</script>

详解io()里面是监听端口

new_msg是推送过来的消息类型 识别号

后台 

<?php
// 指明给谁推送,为空表示向所有在线用户推送
$to_uid = "";
// 推送的url地址,使用自己的服务器地址
$push_api_url = "http://workerman.net:2121/";
$post_data = array(
   "type" => "kline",
   "content" => "这个是推送的测试数据",
   "to" => $to_uid, 
);
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $push_api_url );
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_HEADER, 0 );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_data );
curl_setopt ($ch, CURLOPT_HTTPHEADER, array("Expect:"));
$return = curl_exec ( $ch );
curl_close ( $ch );
var_export($return);

后台监听的端口和前端不一样 分开两个 这两个端口必须和socket_io里面的两个一样

start_io.php

$sender_io = new SocketIO(2120);
//这个端口要和web端监听的端口一致
// 客户端发起连接事件时,设置连接socket的各种事件回调
$sender_io->on('connection', function($socket){
    // 当客户端发来登录事件时触发
    $socket->on('login', function ($uid)use($socket){
        global $uidConnectionMap, $last_online_count, $last_online_page_count;
        // 已经登录过了
        if(isset($socket->uid)){
            return;
        }
        // 更新对应uid的在线数据
        $uid = (string)$uid;
        if(!isset($uidConnectionMap[$uid]))
        {
            $uidConnectionMap[$uid] = 0;
        }
        // 这个uid有++$uidConnectionMap[$uid]个socket连接
        ++$uidConnectionMap[$uid];
        // 将这个连接加入到uid分组,方便针对uid推送数据
        $socket->join($uid);
        $socket->uid = $uid;
        // 更新这个socket对应页面的在线数据
        $socket->emit('update_online_count', "当前<b>{$last_online_count}</b>人在线,共打开<b>{$last_online_page_count}</b>个页面");
    });
    
    // 当客户端断开连接是触发(一般是关闭网页或者跳转刷新导致)
    $socket->on('disconnect', function () use($socket) {
        if(!isset($socket->uid))
        {
             return;
        }
        global $uidConnectionMap, $sender_io;
        // 将uid的在线socket数减一
        if(--$uidConnectionMap[$socket->uid] <= 0)
        {
            unset($uidConnectionMap[$socket->uid]);
        }
    });
});

// 当$sender_io启动后监听一个http端口,通过这个端口可以给任意uid或者所有uid推送数据
$sender_io->on('workerStart', function(){
    // 监听一个http端口
    $inner_http_worker = new Worker('http://0.0.0.0:2010');//这个端口要和后台监听的一样
    // 当http客户端发来数据时触发
    $inner_http_worker->onMessage = function($http_connection, $data){
        global $uidConnectionMap;
        $_POST = $_POST ? $_POST : $_GET;
        // 推送数据的url格式 type=publish&to=uid&content=xxxx
        switch(@$_POST['type']){
            case 'publish'://这个数据类型是后台传过来的数据里面包含的类型
                global $sender_io;
                $to = @$_POST['to'];
                $_POST['content'] = htmlspecialchars(@$_POST['content']);
                // 有指定uid则向uid所在socket组发送数据
                if($to){
                    $sender_io->to($to)->emit('new_msg', $_POST['content']);
                //这个new_msg就是类型 可以换成其他的类型web根据这个类型来判断推过来的数据类型
                // 否则向所有uid推送数据
                }else{
                    $sender_io->emit('new_msg', @$_POST['content']);
                }
                // http接口返回,如果用户离线socket返回fail
                if($to && !isset($uidConnectionMap[$to])){
                    return $http_connection->send('offline');
                }else{
                    return $http_connection->send('ok');
                }
            case 'kline':
                global $sender_io;
                $to = @$_POST['to'];
                $_POST['content'] = htmlspecialchars(@$_POST['content']);
                // 有指定uid则向uid所在socket组发送数据
                if($to){
                    $sender_io->to($to)->emit('kline', $_POST['content']);
                // 否则向所有uid推送数据
                }else{
                    $sender_io->emit('kline', @$_POST['content']);
                }
        }
        return $http_connection->send('fail');
    };

因为socket只能传递字符串推送 所以数据要换成json传递

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值