Dengan populariti Internet dan peranti mudah alih, orang ramai semakin memerlukan alatan kerjasama masa nyata untuk meningkatkan kecekapan kerja. Dengan latar belakang ini, ciri seperti pemesejan segera dan pengeditan kolaboratif dalam alat kolaborasi masa nyata telah menjadi keperluan yang semakin popular. Artikel ini akan memperkenalkan cara melaksanakan alat kerjasama berasaskan web masa nyata dengan bantuan PHP dan WebSocket. Contoh kod yang berkaitan juga akan diberikan.
WebSocket ialah jenis protokol komunikasi Web baharu Ia berdasarkan protokol TCP dan bukannya protokol HTTP dan boleh menyediakan keupayaan komunikasi dua hala. Berbanding dengan teknologi undian Ajax, WebSocket mempunyai kelebihan prestasi masa nyata yang kukuh dan kecekapan komunikasi yang tinggi.
Sebelum ini, jika anda ingin menolak data ke penyemak imbas dalam masa nyata, anda biasanya menggunakan teknologi tinjauan panjang, iaitu pelanggan menghantar permintaan kepada pelayan dan menunggu respons sehingga data baharu tersedia sebelum membalas respons . Masalah dengan pendekatan ini ialah permintaan dan respons adalah berpasangan Jika permintaan kerap, ia akan memberi banyak tekanan kepada pelayan. WebSocket boleh mengekalkan sambungan jangka panjang selepas komunikasi diwujudkan, dan dapat merealisasikan fungsi pelayan secara aktif menolak mesej kepada pelanggan.
Protokol komunikasi WebSocket menggunakan jabat tangan seperti HTTP untuk memulakan sesi baharu, dan kemudian kedua-dua hujung melakukan penghantaran data dua hala. Protokol komunikasi WebSocket boleh mewujudkan sambungan melalui protokol HTTP biasa dan kemudian menukar kepada sambungan WebSocket, mengelakkan keperluan untuk menyambung melalui kaedah atau port khas.
Pertama, dalam kod PHP pada bahagian pelayan, kita perlu mencipta kelas WebSocketServer dan melaksanakan kaedah yang berkaitan:
class WebSocketServer { public function __construct($host, $port){ $this->host = $host; $this->port = $port; $this->sockets = array(); $this->users = array(); } public function run(){ $server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); socket_bind($server, $this->host, $this->port); socket_listen($server); $this->sockets[] = $server; echo "WebSocket服务器运行在 $this->host:$this->port "; while(true){ $new_sockets = $this->sockets; $write = NULL; $except = NULL; socket_select($new_sockets, $write, $except, NULL); foreach($new_sockets as $socket){ if ($socket == $server){ $client = socket_accept($server); $this->sockets[] = $client; $this->users[] = array('socket'=>$client); } else { $bytes = @socket_recv($socket, $buffer, 1024, MSG_DONTWAIT); if ($bytes == 0) { $index = $this->find_user_by_socket($socket); if ($index >= 0) { array_splice($this->users, $index, 1); } socket_close($socket); $key = array_search($socket, $this->sockets); array_splice($this->sockets, $key, 1); } else { $index = $this->find_user_by_socket($socket); if($index >= 0) { $msg = $buffer; $this->handle_message($msg, $this->users[$index]); } } } } } } private function find_user_by_socket($socket){ $found = -1; foreach($this->users as $index => $user){ if ($user['socket'] == $socket){ $found = $index; break; } } return $found; } private function handle_message($msg, $user) { // 处理新消息 } }
Dalam protokol WebSocket, mesej bermula dengan pengepala panjang 4~10 bait , diikuti dengan data sebenar. Dalam kod di atas, kita perlu menghuraikan pengepala panjang dan kemudian membaca bahagian data panjang yang sepadan.
private function handle_message($msg, $user) { if(strlen($msg) === 0) { return; } $code = ord(substr($msg, 0, 1)) & 0x0F; switch ($code){ case 0x01: // 文本数据 $msg = substr($msg, 1); break; case 0x02: // 二进制数据 $msg = substr($msg, 1); break; case 0x08: // 连接关闭 $index = $this->find_user_by_socket($user['socket']); if ($index >= 0) { array_splice($this->users, $index, 1); } socket_close($user['socket']); $key = array_search($user['socket'], $this->sockets); array_splice($this->sockets, $key, 1); return; case 0x09: // ping case 0x0A: // pong return; default: return; } // 处理新消息 }
Dalam kaedah handle_message kita boleh mengendalikan mesej baru yang diterima daripada pelanggan seperti lambakan dan hantar kepada pelanggan lain.
Di pihak pelanggan, kita perlu menggunakan JavaScript untuk membuat sambungan WebSocket dan menghantar serta menerima mesej. Berikut ialah kod JavaScript untuk menyambung ke pelayan WebSocket:
var ws = new WebSocket("ws://localhost:8080/"); ws.onopen = function() { console.log("Connected to WebSocket server"); }; ws.onmessage = function(evt) { console.log("Received message: " + evt.data); }; ws.onclose = function(evt) { console.log("Disconnected from WebSocket server"); };
Dalam kod di atas, kami menggunakan pembina WebSocket untuk mencipta objek WebSocket dan menyambungkannya ke pelayan WebSocket. Kami juga menyediakan beberapa pendengar acara (onopen, onmessage dan onclose) untuk memantau status sambungan WebSocket dan menerima mesej.
Apabila kita ingin menghantar data ke pelayan WebSocket, kita boleh menggunakan kaedah hantar objek WebSocket:
ws.send("Hello, WebSocket server!");
Apabila mesej baharu daripada pelayan WebSocket diterima, acara onmessage dicetuskan, dan kita boleh mendapatkan mesej yang diterima. mesej daripada objek acara kepada data.
Dengan sokongan komunikasi WebSocket, kami boleh membangunkan aplikasi alat kerjasama sebenar. Dalam alatan kerjasama, fungsi berikut perlu dilaksanakan:
class WebSocketChat { private $users = array(); public function onOpen($user){ $this->users[$user['id']] = $user; $this->sendToAll(array('type'=>'notice','from'=>'System','msg'=>"{$user['name']}进入聊天室")); } public function onMessage($user, $msg){ $this->sendToAll(array('type'=>'msg','from'=>$user['name'],'msg'=>$msg)); } public function onClose($user){ unset($this->users[$user['id']]); $this->sendToAll(array('type'=>'notice','from'=>'System','msg'=>"{$user['name']}离开聊天室")); } private function sendToAll($msg){ foreach($this->users as $user){ $this->send($user, $msg); } } private function send($user, $msg){ socket_write($user['socket'], $this->encode(json_encode($msg))); } private function encode($msg){ $len = strlen($msg); if($len <= 125){ } if($len <= 65535){ } } }
Atas ialah kandungan terperinci Bagaimana untuk membangunkan alat kerjasama masa nyata menggunakan PHP dan WebSocket. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!