作者

一、准备工作

总所周知,即时通讯的应用在目前的市场需求中是很广泛的,要想实现比较高级的应用,首先要认识即时通讯到底怎么回事,初始workman请参考如下地址:https://itfun.tv/chapters/185/body

二、功能需求

本例主要实现一个当后端数据变化时,前端显示的数据实时变化。以之前小米商城会员统计图表功能为例。 当会员列表的会员性别发生变化时,前端图表实时变动。接下来,我们来实现此功能。

三、具体实现

1、首先去后台的会员管理模块中,加载出会员表中所有数据。并使用ajax实现男女性别的切换。部分代码如下:

@section('js')
    <script>
       $('.change_sex').click(function () {
           var info = {
               id: $(this).parents('tr').data('id'),
               attr: $(this).data('attr')
           };
           var _this = $(this);
           $.ajax({
               type: "PATCH",
               url: "/admin/shop/customers/change_attr",
               data: info,
               success: function () {
                   _this.toggleClass('am-icon-male am-icon-female');
               }
           })
       })
    </script>
@endsection
public function change_attr(Request $request)
{
    $customer = Customer::find($request->id);
    $attr = $request->attr;
    $customer->sex = $attr == 1 ? 2 : 1;
    $customer->save();
}

2、后台首页使用Echarts以图标的形式显示出会员的男女性别统计。注意使用接口开发。

1、路由:在api.php文件中写上如下内容

Route::namespace('Api')->group(function () {
    //性别统计
    $this->get('sex_total', 'EchartController@sex_total');

    $this->post('bind', 'EchartController@bind')->name('bind');
});

2、控制器:在对应的控制器中查出当前会员表的男女性别数量统计的数据,并返回json数据

public function sex_total()
{
    $data = [
        ['value' => Customer::where('sex', 1)->count(), 'name' => '男'],
        ['value' => Customer::where('sex', 2)->count(), 'name' => '女']
    ];

    return response()->json($data);
}

3、前端展示:在后台首页中以图表形式展示会员信息,此处代码省略。参考Echarts文档自行完成。

4、加入workerman:在项目中创建一个socket文件夹,把下载好的GatewayWorker框架粘贴进来。下载地址:https://itfun.tv/chapters/185/body

5、打开终端,进入Laravel项目,执行命令:composer require workerman/gatewayclient 6、进入后台的Customer控制器对应的方法中,写上监听地址,并通过sendToGroup方法返回最新数据。具体代码如下:

use GatewayClient\Gateway;

public function change_attr(Request $request)
{
    Gateway::$registerAddress = '127.0.0.1:1238'; //此处地址根据start_gateway.php文件来。
    $customer = Customer::find($request->id);
    $attr = $request->attr;
    $customer->sex = $attr == 1 ? 2 : 1;
    $customer->save();

    $data = [
        ['value' => Customer::where('sex', 1)->count(), 'name' => '男'],
        ['value' => Customer::where('sex', 2)->count(), 'name' => '女']
    ];

    Gateway::sendToGroup('sex', json_encode($data));
}

修改start_gateway.php文件

//把原有的TCP改成websocket
$gateway = new Gateway("websocket://0.0.0.0:8282");

修改Events.php文件

/**
* 当客户端发来消息时触发
* @param int $client_id 连接id
* @param mixed $message 具体消息
*/
public static function onMessage($client_id, $message)
{
    //向所有人发送 
        //Gateway::sendToAll("$client_id said $message\r\n");
}

7、后端Echart控制器增加一个接口,用来绑定用户的id,因为每个客户端代表一个用户。

use GatewayClient\Gateway;

public function bind(Request $request)
{
    Gateway::$registerAddress = '127.0.0.1:1238';
    Gateway::joinGroup($request->client_id, 'sex');
}

8、修改后台首页js,代码如下:

ws = new WebSocket("ws://127.0.0.1:8282");
ws.onmessage = function (e) {
 //console.log(e);
 var data = eval("(" + e.data + ")");

 var type = data.type || '';
    //console.log(type);
 if (type == 'init') {
     $.post('/api/bind', {client_id: data.client_id});
 }

 if (data.type) {
     return;
 }

 var option = {
     series: [
         {data: data}
     ]
 };

 myChart.setOption(option);
};

9、修改Events.php文件代码如下:

public static function onConnect($client_id)
{
   // 向当前client_id发送数据 
    //Gateway::sendToClient($client_id, "Hello $client_id\r\n");
    // 向所有人发送
    //Gateway::sendToAll("$client_id login\r\n");

   Gateway::sendToClient($client_id, json_encode([
       'type' => 'init',
       'client_id' => $client_id
   ]));
}

10、修改后的后台首页完整的js代码如下:

$(function () {
  ws = new WebSocket("ws://127.0.0.1:8282");
  ws.onmessage = function (e) {
      //console.log(e);
      var data = eval("(" + e.data + ")");

      var type = data.type || '';
        //console.log(type);
      if (type == 'init') {
          $.post('/api/bind', {client_id: data.client_id});
      }

      if (data.type) {
          return;
      }

      var option = {
          series: [
              {data: data}
          ]
      };

      myChart.setOption(option);
  };
  var myChart = echarts.init(document.getElementById('main'), 'macarons');

  $.get('/api/sex_total').done(function (data) {
      // 指定图表的配置项和数据
      var option = {
          title: {
              text: '某站点用户访问来源',
              subtext: '纯属虚构',
              x: 'center'
          },
          tooltip: {
              trigger: 'item',
              formatter: "{a} <br/>{b} : {c} ({d}%)"
          },
          legend: {
              orient: 'vertical',
              left: 'left',
              data: ['', '']
          },
          series: [
              {
                  name: '访问来源',
                  type: 'pie',
                  radius: '55%',
                  center: ['50%', '60%'],
                  data: data,
                  itemStyle: {
                      emphasis: {
                          shadowBlur: 10,
                          shadowOffsetX: 0,
                          shadowColor: 'rgba(0, 0, 0, 0.5)'
                      }
                  }
              }
          ]
      };

      // 使用刚指定的配置项和数据显示图表。
      myChart.setOption(option);
  });
})

最后,终端启动服务,cd socket/GatewayWorker,执行命令:php start.php start。这是Mac电脑的启动命令,Windows请参考官方文档。 测试,开两个不同的浏览器,一个定位到后台会员列表页,一个定位到图标显示页,点击改变性别,另外一个浏览器图表实时变动。大功告成!!!

转载请注明,来自https://itfun.tv/news/140