天天看點

websocket 研究

1. 保證php開啟sockets,找到php.ini,找到   ;extension=sockets  去掉前面的 ; 

指令行測試是否開啟:php c:\...\isSockets.php

isSockets.php

<?php
  if(extension_loaded('sockets')){
    echo "已開啟";
  }else{
    echo "未開啟";
  }
?>           

2.

目前較好的開發即時通訊的架構,推薦:workerman,and  swoole  。

開發中。(使用了workerman)

伺服器端,啟動: 指令模式shell  :php your/path/server.php

注意。傳輸模式的設定,預設傳文本。如果開發語言等功能,設定arraybuffer

<?php
	use Workerman\Worker;
	require_once __DIR__ . '/Workerman/Autoloader.php';
use Workerman\Protocols\Websocket;
	// 建立一個Worker監聽2345端口,使用http協定通訊
    $http_worker = new Worker("websocket://127.0.0.1:8000");
	// $http_worker = new Worker("websocket://172.25.204.1:8000");

	// 啟動4個程序對外提供服務
	$http_worker->count = 4;
	$global_uid = 0;
    $client = []; //儲存用戶端資訊
    $out = [];
    // 當用戶端連上來時配置設定uid,并儲存連接配接,并通知所有用戶端
    function handle_connection($connection)
    {
        global $http_worker, $global_uid;
        
        // 為這個連接配接配置設定一個uid
        $connection->uid = ++$global_uid;
    }
    // 當用戶端發送消息過來時,轉發給所有人
    function handle_message($connection, $data)
    {
      global $http_worker,$client,$out;
      // $connection->websocketType = Websocket::BINARY_TYPE_BLOB;   //傳輸文本
       $connection->websocketType = Websocket::BINARY_TYPE_ARRAYBUFFER;   //設定傳輸二進制資料
        foreach($http_worker->connections as $conn)
        {
            $conn->send($data);
            // $conn->send('users:'.json_encode($out));
            // $conn->send($data);
            // $conn->send($connection->uid);
        }
    }

    // 當用戶端斷開時,廣播給所有用戶端
    function handle_close($connection)
    {
        global $http_worker,$client,$out;
        //退出的時候删除使用者
        foreach ($out as $key => $value) {
          
            if ($value["id"] == $connection->uid) {
                // echo "delet array";
                // unset($out[$key]);
            }
        }
        foreach($http_worker->connections as $conn)
        {
            $conn->send("user[{$connection->uid}] 退出聊天室");
        }
    }

    $http_worker->onConnect = 'handle_connection';  
	$http_worker->onMessage = 'handle_message';  
	$http_worker->onClose = 'handle_close';  

	Worker::runAll();           

客戶度:

var ws = new WebSocket("ws://127.0.0.1:8000");  //對應的域名位址和端口
	ws.binaryType = 'arraybuffer';    //設定用戶端傳資料的模式           

接收資料

// onmessage 通訊
// 收到的是 blob 資料
	ws.binaryType = "blob";
	ws.onmessage = function (res) {
		if(typeof(res.data) == "string"){
			console.log('get data is string');
		}
		if((res.data) instanceof Blob) { // 判斷是否是二進制資料類型,并處理二進制資訊
			console.log('get data is Blob...');
			var  data_blob = new Blob([res.data],{type:"audio/wav"});//接收檔案,并還原可播放音頻檔案
		}
				
		dataRec = data_blob;
		// 處理接收到的blob資料;
		var reader = new FileReader();
		// var firstBlob = res.data;
		// reader.readAsBinaryString(firstBlob);  //該方法被w3c剔除,用readAsArrayBuffer替代。
		// reader.readAsArrayBuffer(res.data);
		var s = reader.readAsText(res.data); //
                reader.addEventListener("loadend",function(res){
        	
        	    var buffer = res.currentTarget.result;
        	
        	if (buffer.indexOf("say")!=-1) {
        		var said = $.parseJSON(buffer);
        		saidHtml = `<div>${said.userName} 說 : ${said.content}</div>`;
        		$("#chatContainer").append(saidHtml+'<br/>');
        	}else if(buffer.indexOf("退出聊天")!=-1){
        		saidHtml = `<div>${buffer}</div>`;
        		$("#chatContainer").append(saidHtml+'<br/>');
        	}
        	else{
        		html = `<div id="${msgId}" class="userRec">發來了語音</div>`;
			$("#chatContainer").append(html+'<br/>');
        		return;
        	} 
            })
	}            

尚未完善。待更。

參考文檔資料。

ws.onmessage = function(event){
         if (event.data instanceof Blob) {
            var blob = event.data;
            //先把blob進行拆分,第一個位元組是辨別
            var newblob=blob.slice(0,1);
            //js中的blob沒有沒有直接讀出其資料的方法,通過FileReader來讀取相關資料
            var reader = new FileReader();
            reader.readAsBinaryString(newblob);
            var imgFlag;          
           //  當讀取操作成功完成時調用.
            reader.onload = function(evt){  
            if(evt.target.readyState == FileReader.DONE){  
                var imgFlag = evt.target.result; 
                if(imgFlag=='@'){
                    img=document.getElementById('er');
                }else if(imgFlag=='A'){
                    img=document.getElementById('photo');
                }else{
                    img=document.getElementById('photo');
                }
                newblob=blob.slice(1,blob.size);
                window.URL = window.URL || window.webkitURL;
                var source = window.URL.createObjectURL(newblob);
                img.src=source;
                }
                
            }

        }      
websocket 研究