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;
}
}
}
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsISM4MDOygTM2EzNwUDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)