激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

香港云服务器
服務器之家 - 編程語言 - PHP教程 - workerman結合laravel開發在線聊天應用的示例代碼

workerman結合laravel開發在線聊天應用的示例代碼

2019-08-30 10:08逍遙俠 PHP教程

聊天功能是很常見的一種功能,Workerman是一款開源高性能異步PHP socket即時通訊框架。這篇文章主要介紹了workerman結合laravel開發在線聊天應用,感興趣的小伙伴們可以參考一下

項目背景:

最近由于公司的業務需求,需要用到聊天功能。而且有比較多的個性化需求需要定制。之前使用別人的聊天組件是基于微擎的。如果要移植到普通的H5在邏輯修改還有定制上存在比較多的困難。為此只能克服困難,自己搭建一個吧

什么是Workerman?

Workerman是一款 開源 高性能異步 PHP socket即時通訊框架 。支持高并發,超高穩定性,被廣泛的用于手機app、移動通訊,微信小程序,手游服務端、網絡游戲、PHP聊天室、硬件通訊、智能家居、車聯網、物聯網等領域的開發。 支持TCP長連接,支持Websocket、HTTP等協議,支持自定義協議。擁有異步Mysql、異步Redis、異步Http、MQTT物聯網客戶端、異步消息隊列等眾多高性能組件。

開始實戰吧!

1.第一步我們先把workerman里需要用到的擴展composer下來吧

1"workerman/gateway-worker": "^3.0",
2"workerman/gatewayclient": "^3.0",
3"workerman/workerman": "^3.5",

2.第二步我們到官方網站把demo全部下載下來,然后放到我們項目中的目錄

workerman結合laravel開發在線聊天應用的示例代碼

圖片中我就把整個項目都放在了HTTP/Controller/Workerman中。

3.第三步我們需要把把以下3個文件的引用部分修改為以下。不然會報路徑錯誤

start_businessworker,start_gateway,start_register

1require_once __DIR__ . '/../../../../../vendor/autoload.php';

4.修改完成后我們就可以在liunx直接運行對應的啟動文件

1php start.php start -d

如果你是在window下就雙擊start_for_win.bat運行

5.運行成功后,你就應該可以看到以下的界面

workerman結合laravel開發在線聊天應用的示例代碼

到此我們搭建基于workerman的通信環境就已經完成。接下來我們就可以根據自己的項目需求進行開發。在此向大家重點說明。我們所有的聊天是邏輯都在目錄中的Events.php進行修改。

---------------------------------華麗分割線---------------------------------------------------

下面我給大家貼一下我編寫的部分份代碼。

Event.php

001<?php
002/**
003 * This file is part of workerman.
004 *
005 * Licensed under The MIT License
006 * For full copyright and license information, please see the MIT-LICENSE.txt
007 * Redistributions of files must retain the above copyright notice.
008 *
009 * @author walkor<walkor@workerman.net>
010 * @copyright walkor<walkor@workerman.net>
013 */
014 
015/**
016 * 用于檢測業務代碼死循環或者長時間阻塞等問題
017 * 如果發現業務卡死,可以將下面declare打開(去掉//注釋),并執行php start.php reload
018 * 然后觀察一段時間workerman.log看是否有process_timeout異常
019 */
020//declare(ticks=1);
021 
022/**
023 * 聊天主邏輯
024 * 主要是處理 onMessage onClose
025 */
026use \GatewayWorker\Lib\Gateway;
027 
028class Events
029{
030  /**
031   * 作者:何志偉
032   * 當客戶端連接上來的時候
033   * 創建時間:2018/10/25
034   * @param $client_id 此ID為gatewayworker 自動生成ID
035   */
036  public static function onConnect($client_id)
037  {
038    Gateway::sendToClient($client_id, json_encode(array(
039      'type'   => 'init',
040      'client_id' => $client_id
041    )));
042  }
043 
044 
045  /**
046   * 有消息時
047   * @param int $client_id
048   * @param mixed $message
049   */
050  public static function onMessage($client_id, $message)
051  {
052    // debug
053    echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']} client_id:$client_id session:".json_encode($_SESSION)." onMessage:".$message."\n";
054 
055    // 客戶端傳遞的是json數據
056    $message_data = json_decode($message, true);
057    if(!$message_data)
058    {
059      return ;
060    }
061 
062    // 根據類型執行不同的業務
063    switch($message_data['type'])
064    {
065      // 客戶端回應服務端的心跳
066      case 'pong':
067        return;
068      // 客戶端登錄 message格式: {type:login, name:xx, room_id:1} ,添加到客戶端,廣播給所有客戶端xx進入聊天室
069      case 'login':
070        // 判斷是否有房間號
071        if(!isset($message_data['room_id']))
072        {
073          throw new \Exception("\$message_data['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']} \$message:$message");
074        }
075 
076        // 把房間號昵稱放到session中
077        $room_id = $message_data['room_id'];
078        $client_name = htmlspecialchars($message_data['client_name']);
079        $_SESSION['room_id'] = $room_id;
080        $_SESSION['client_name'] = $client_name;
081 
082 
083        // 獲取房間內所有用戶列表
084        $clients_list = Gateway::getClientSessionsByGroup($room_id);
085        foreach($clients_list as $tmp_client_id=>$item)
086        {
087          $clients_list[$tmp_client_id] = $item['client_name'];
088        }
089//        $clients_list[$client_id] = $client_name;
090 
091        // 轉播給當前房間的所有客戶端,xx進入聊天室 message {type:login, client_id:xx, name:xx}
092        $new_message = array('type'=>$message_data['type'], 'client_id'=>$client_id, 'client_name'=>htmlspecialchars($client_name), 'time'=>date('Y-m-d H:i:s'),'to'=>$message_data['to'],'room_id'=>$message_data['room_id'],
093          'from'=>$message_data['from'],'tag'=>$message_data['tag']);
094        Gateway::sendToGroup($room_id, json_encode($new_message));
095        Gateway::joinGroup($client_id, $room_id);
096 
097        // 給當前用戶發送用戶列表
098        $new_message['client_list'] = $clients_list;
099        Gateway::sendToCurrentClient(json_encode($new_message));
100        return;
101 
102      // 客戶端發言 message: {type:say, to_client_id:xx, content:xx}
103      case 'say':
104        // 非法請求
105        if(!isset($_SESSION['room_id']))
106        {
107          throw new \Exception("\$_SESSION['room_id'] not set. client_ip:{$_SERVER['REMOTE_ADDR']}");
108        }
109        $room_id = $_SESSION['room_id'];
110        $client_name = $_SESSION['client_name'];
111 
112        // 私聊
113//        if($message_data['to_client_id'] != 'all')
114//        {
115//          $new_message = array(
116//            'type'=>'say',
117//            'from_client_id'=>$client_id,
118//            'from_client_name' =>$client_name,
119//            'to_client_id'=>$message_data['to_client_id'],
120//            'content'=>"<b>對你說: </b>".nl2br(htmlspecialchars($message_data['content'])),
121//            'time'=>date('Y-m-d H:i:s'),
122//          );
123//          Gateway::sendToClient($message_data['to_client_id'], json_encode($new_message));
124//          $new_message['content'] = "<b>你對".htmlspecialchars($message_data['to_client_name'])."說: </b>".nl2br(htmlspecialchars($message_data['content']));
125//          return Gateway::sendToCurrentClient(json_encode($new_message));
126//        }
127 
128        $new_message = array(
129          'type'=>'say',
130          'from_client_id'=>$client_id,
131          'from_client_name' =>$client_name,
132          'to_client_id'=>'all',
133          'content'=>nl2br(htmlspecialchars($message_data['content'])),
134          'time'=>date('Y-m-d H:i:s'),
135 
136        );
137        return Gateway::sendToGroup($room_id ,json_encode($new_message));
138    }
139  }
140  /**
141   * 當客戶端斷開連接時
142   * @param integer $client_id 客戶端id
143   */
144  public static function onClose($client_id)
145  {
146    // debug
147    echo "client:{$_SERVER['REMOTE_ADDR']}:{$_SERVER['REMOTE_PORT']} gateway:{$_SERVER['GATEWAY_ADDR']}:{$_SERVER['GATEWAY_PORT']} client_id:$client_id onClose:''\n";
148 
149    // 從房間的客戶端列表中刪除
150    if(isset($_SESSION['room_id']))
151    {
152      $room_id = $_SESSION['room_id'];
153      $new_message = array('type'=>'logout', 'from_client_id'=>$client_id, 'from_client_name'=>$_SESSION['client_name'], 'time'=>date('Y-m-d H:i:s'));
154      Gateway::sendToGroup($room_id, json_encode($new_message));
155    }
156  }
157 
158}

客戶端頁面

001<!DOCTYPE html>
002<html lang="en">
003<head>
004  <meta charset="UTF-8">
005  <title>與{{$to->name}}的對話</title>
006  <script type="text/javascript" src="{{asset('js')}}/swfobject.js"></script>
007  <script type="text/javascript" src="{{asset('js')}}/web_socket.js"></script>
008  <script type="text/javascript" src="{{asset('js')}}/jquery.min.js"></script>
009  <link href="{{asset('css')}}/jquery-sinaEmotion-2.1.0.min.css" rel="external nofollow" rel="stylesheet">
010  <link href="{{asset('css')}}/bootstrap.min.css" rel="external nofollow" rel="stylesheet">
011  <link href="{{asset('css')}}/style.css" rel="external nofollow" rel="stylesheet">
012  <script type="text/javascript" src="{{asset('js')}}/jquery-sinaEmotion-2.1.0.min.js"></script>
013 
014  {{--<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>--}}
015 
016</head>
017<style>
018  #sinaEmotion {
019    z-index: 999;
020    width: 373px;
021    padding: 10px;
022    display: none;
023    font-size: 12px;
024    background: #fff;
025    overflow: hidden;
026    position: absolute;
027    border: 1px solid #e8e8e8;
028    top: 100px;
029    left: 542.5px;
030  }
031</style>
032<body onload="connect();" style="margin: auto; text-align: center;">
033<div style="margin: auto;">
034  <div style="border: 1px solid red; height: 40px; width: 500px; margin: auto;">
035    {{--對話窗口頭部--}}
036    <div>
037      <div style="width: 80px; height: 40px; border: 1px solid blue; float: left">
038        <img src="{{$to->heading}}" width="80px" height="40px">
039      </div>
040      <div style="width: 150px; height: 40px; border: 1px solid blue; float: left">
041        {{$to->name}}
042      </div>
043    </div>
044    {{--//對話窗口內容--}}
045    <div class="content" style="width: 500px; height: 400px; border: 1px solid green; margin-top: 40px; overflow-y: auto">
046      {{--對方的頭像與文字--}}
047      {{--<div style="min-height: 50px;margin-top: 10px;">--}}
048        {{--<div style="width: 50px;height: 50px; border: 1px solid red; margin-left:10px; float: left">--}}
049          {{--<img src="{{$to->heading}}" width="50px" height="50px">--}}
050        {{--</div>--}}
051        {{--<div style="border: 1px solid red; float: left; min-height: 50px" >dsadsadsadsadsa</div>--}}
052      {{--</div>--}}
053      {{--我的頭像與文字--}}
054      {{--<div style= "min-height:50px;margin-top: 10px;">--}}
055        {{--<div style="width: 50px;height: 50px; border: 1px solid red; margin-left:10px; float: right">--}}
056          {{--<img src="{{$from->heading}}" width="50px" height="50px">--}}
057        {{--</div>--}}
058        {{--<div style="border: 1px solid red; float: right; min-height: 50px" >dsadsadsadsadsa</div>--}}
059      {{--</div>--}}
060    </div>
061    {{--對話發送窗口--}}
062    <form onsubmit="return onSubmit(); return false;" id="ajaxfrom">
063      <input type="hidden" name="to" value="{{$to->id}}">
064      <input type="hidden" name="from" value="{{$from->id}}">
065      <input type="hidden" name="room_id" value="{{$room}}">
066      <input type="hidden" name="tag" value="{{$tag}}">
067      <textarea id="textarea" name="content" class="Input_text" style="margin: 0px; width: 501px; height: 213px;"></textarea>
068      <div class="say-btn">
069        <input type="button" class="btn btn-default face pull-left" value="表情" />
070        <button type="submit" class="btn btn-default">發表</button>
071      </div>
072    </form>
073    房間號{{$room}}
074  </div>
075</div>
076 
077</body>
078</html>
079<script type="text/javascript">
080  if (typeof console == "undefined") {  this.console = { log: function (msg) { } };}
081  // 如果瀏覽器不支持websocket,會使用這個flash自動模擬websocket協議,此過程對開發者透明
082  WEB_SOCKET_SWF_LOCATION = "/swf/WebSocketMain.swf";
083  // 開啟flash的websocket debug
084  WEB_SOCKET_DEBUG = true;
085  var ws, name, client_list={};
086  var to_client_id="";
087 
088  // 連接服務端初始化函數
089  function connect() {
090    // 創建websocket 屆時可以替換為對應的服務器地址
091    ws = new WebSocket("ws://"+document.domain+":7272");
092    // 當socket連接打開時,輸入用戶名
093    ws.onopen = onopen;
094    // 當有消息時根據消息類型顯示不同信息
095    ws.onmessage = onmessage;
096    //當連接丟失時,調用連接方法嘗試重新連接
097    ws.onclose = function() {
098      console.log("連接關閉,定時重連");
099      connect();
100    };
101    //當操作報錯時,返回異常錯誤
102    ws.onerror = function() {
103      console.log("出現錯誤");
104    };
105 
106    //發送ajax獲取當前房間的通話記錄
107    $.post("/get_record", { "room":"{{$room}}" },
108      function(msg){
109        $.each(msg,function (v,k) {
110          console.log(k);
111          //判斷
112          if(k.tag!="{{$tag}}"){
113            $(".content").append(
114              '<div style="min-height: 50px;margin-top: 10px;">' +
115              '<div style="width: 50px;height: 50px; border: 1px solid red; margin-left:10px; float: left">'+
116              '<img src="{{$to->heading}}" width="50px" height="50px">'+
117              '</div>'+
118              '<div style="border: 1px solid red; float: left; min-height: 50px" >'+k.content+'</div>'+
119              '<div>'
120            ).parseEmotion();
121          }else{
122            $(".content").append(
123              '<div style="min-height: 50px;margin-top: 10px;">' +
124              '<div style="width: 50px;height: 50px; border: 1px solid red; margin-left:10px; float: right">'+
125              '<img src="{{$from->heading}}" width="50px" height="50px">'+
126              '</div>'+
127              '<div style="border: 1px solid red; float: right; min-height: 50px" >'+k.content+'</div>'+
128              '<div>'
129            ).parseEmotion();
130          }
131        })
132      });
133  }
134 
135  // 連接建立時發送登錄信息
136  function onopen()
137  {
138    var login_data='{"type":"login","client_name":"{{$from->name}}","room_id":"{{$room}}","to":"{{$to->id}}","from":"{{$from->id}}","tag":"{{$tag}}"}';
139 
140    ws.send(login_data);
141    console.log('登錄成功')
142  }
143 
144  // 服務端發來消息時
145  function onmessage(e)
146  {
147    var data = JSON.parse(e.data);
148    switch(data['type']){
149      // 服務端ping客戶端心跳
150      case 'ping':
151        ws.send('{"type":"pong"}');
152        break;
153      // 登錄 更新用戶列表
154      case 'login':
155        //講需要的發送ID保存到本地to_client_id變量中
156        for(var p in data['client_list']){
157          to_client_id=p;
158        }
159        console.log(to_client_id);
160        break;
161      // 發言
162      case 'say':
163        console.log(data);
164        say(data['from_client_id'], data['from_client_name'], data['content'], data['time']);
165        break;
166      // 用戶退出 更新用戶列表
167      case 'logout':
168        console.log(data);
169        break;
170      case 'init':
171        //此處可以發送ajax用于綁定不同的用戶ID和client
172        console.log(data);
173        break;
174 
175    }
176  }
177 
178  // 提交對話
179  function onSubmit() {
180    //先檢查當前的對話是否超過20條記錄數
181    var count=true;
182    //發送ajax獲取當前房間的通話記錄
183    $.ajax({
184      url: "/check_count",
185      type: "post",
186      async:false,
187      // cache: false,
188      // contentType: false,
189      // processData: false,
190      data:{
191      'room':"1",
192      },
193      success: function (msg) {
194        if(msg>10){
195          alert('當前的對話已經超過次數,請購買對應服務')
196          count=false;
197        }
198      }
199 
200    });
201 
202 
203    if(count){
204      var neirong=$("#textarea").val().replace(/"/g, '\\"').replace(/\n/g,'\\n').replace(/\r/g, '\\r');
205      //ajax先把對應的內容發送到后臺錄入,回調成功后才把信息發送
206      var fm=$("#ajaxfrom")[0];
207      var formData = new FormData(fm);
208      $.ajax({
209        url: "/record",
210        type: "post",
211        cache: false,
212        contentType: false,
213        processData: false,
214        data: formData,
215        beforeSend:function(){
216 
217        },
218        success: function (msg) {
219 
220          if(msg.code=="0"){
221            ws.send('{"type":"say","to_client_id":"all","to_client_name":"{{$to->name}}","content":"'+neirong+'"}');
222            //清空文本框內容
223            $("#textarea").val("");
224            //強制定位光標
225            $("#textarea").focus();
226          }else{
227 
228          }
229 
230        }
231 
232      });
233    }
234 
235    return false;
236 
237 
238  }
239 
240 
241 
242  // 發言
243  function say(from_client_id, from_client_name, content, time){
244    //判斷當前的用戶名稱與發送消息的名稱是否一致
245    if( "{{$from->name}}" == from_client_name){
246      $(".content").append(
247        '<div style="min-height: 50px;margin-top: 10px;">' +
248        '<div style="width: 50px;height: 50px; border: 1px solid red; margin-left:10px; float: right">'+
249        '<img src="{{$from->heading}}" width="50px" height="50px">'+
250        '</div>'+
251        '<div style="border: 1px solid red; float: right; min-height: 50px" >'+content+'</div>'+
252        '<div>'
253      ).parseEmotion();
254    }else{
255      $(".content").append(
256        '<div style="min-height: 50px;margin-top: 10px;">' +
257        '<div style="width: 50px;height: 50px; border: 1px solid red; margin-left:10px; float: left">'+
258        '<img src="{{$to->heading}}" width="50px" height="50px">'+
259        '</div>'+
260        '<div style="border: 1px solid red; float: left; min-height: 50px" >'+content+'</div>'+
261        '<div>'
262      ).parseEmotion();
263    }
264 
265    // $("#dialog").append('<div class="speech_item"><img src="http://lorempixel.com/38/38/?'+from_client_id+'" class="user_icon" /> '+from_client_name+' <br> '+time+'<div style="clear:both;"></div><p class="triangle-isosceles top">'+content+'</p> </div>').parseEmotion();
266  }
267  $(function(){
268    //全局用戶ID
269    select_client_id = 'all';
270 
271    //如果發送的用戶有變化則對應的用戶ID進行替換
272    $("#client_list").change(function(){
273      select_client_id = $("#client_list option:selected").attr("value");
274    });
275    //表情選擇
276    $('.face').click(function(event){
277      $(this).sinaEmotion();
278      event.stopPropagation();
279    });
280  });
281 
282  // document.write('<meta name="viewport" content="width=device-width,initial-scale=1">');
283  $("textarea").on("keydown", function(e) {
284    //按enter鍵自動提交
285    if(e.keyCode === 13 && !e.ctrlKey) {
286      e.preventDefault();
287      $('form').submit();
288      return false;
289    }
290 
291    // 按ctrl+enter組合鍵換行
292    if(e.keyCode === 13 && e.ctrlKey) {
293      $(this).val(function(i,val){
294        return val + "\n";
295      });
296    }
297  });
298 
299</script>

這兩個代碼片段其實就是主要運行的核心片段。其他框架的自帶參數需要各位自己去根據文檔去調試優化。到此基于workerman的聊天用于功能demo已經搭建完畢。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
557
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 精品国产一区二区三区四区阿崩 | 欧产日产国产精品乱噜噜 | 国产一区二区视频在线播放 | 久久亚洲网 | 日本看片一区二区三区高清 | 国产美女的小嫩bbb图片 | 成人超碰 | 亚洲精品久久久久www | av播播 | 视频一区二区三区视频 | 国产日韩亚洲 | 综合网日日天干夜夜久久 | www视频免费在线观看 | 国产精品久久久久久久久久久久久久久久 | 超久久| 久久国产免费视频 | 日韩视频在线视频 | 黄网站免费观看视频 | 久章草影院 | 国产精品99久久久久久董美香 | 久久精品国产99国产精品澳门 | 国产黄色一区二区 | 欧美亚洲另类在线 | 日美黄色片 | www国产网站| 久久久久久久久成人 | 91成人久久 | 中国大陆一级毛片 | 蜜桃视频观看麻豆 | 草草视频在线播放 | 国产免费成人 | www.91在线观看 | 青青青在线免费 | 主播粉嫩国产在线精品 | 欧美第1页| 国产青草视频在线观看 | 色综合一区二区 | 日韩黄在线 | 久久视讯 | 92自拍视频 | 国产艳妇av视国产精选av一区 |