本文主要是介绍Unity CocosCreator PHP WebSocket 三方会谈,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
效果预览:
PHP 服务器:
<?php
/*** Created by xwx* Date: 2017/10/18* Time: 14:33*/class SocketService
{private $address = '0.0.0.0';private $port = 12345;private $_sockets;public function __construct($address = '', $port = ''){if (!empty($address)) {$this->address = $address;}if (!empty($port)) {$this->port = $port;}}public function service(){//获取tcp协议号码。$tcp = getprotobyname('tcp');$sock = socket_create(AF_INET, SOCK_STREAM, $tcp);socket_set_option($sock, SOL_SOCKET, SO_REUSEADDR, 1);if ($sock < 0) {throw new Exception('failed to create socket: ' . socket_strerror($sock) . "\n");}socket_bind($sock, $this->address, $this->port);socket_listen($sock, $this->port);echo "listen on $this->address $this->port ... \n";$this->_sockets = $sock;}public function run(){$this->service();$clients[] = $this->_sockets;while (true) {$changes = $clients;$write = null;$except = null;socket_select($changes, $write, $except, null);foreach ($changes as $key => $_sock) {if ($this->_sockets == $_sock) {//判断是不是新接入的socketif (($newClient = socket_accept($_sock)) === false) {die('failed to accept socket: ' .socket_strerror($_sock) ."\n");}$line = trim(socket_read($newClient, 1024));$this->handshaking($newClient, $line);//获取client ipsocket_getpeername($newClient, $ip);$clients[$ip] = $newClient;echo "Client ip:{$ip} \n";echo "Client msg:{$line} \n";} else {$len_read = socket_recv($_sock, $buffer, 2048, 0);if ($len_read === false) {// no data// echo 'no data' . PHP_EOL;// socket_close($_sock);// continue;} else {$msg = $this->message($buffer);$response = trim($msg);echo "{$key} clinet msg:", $response, "\n";//在这里业务代码foreach ($clients as $MySocket) {$this->send($MySocket, $response);}// echo "{$key} clinet msg:", $response, "\n";// $this->send($_sock, $response);// fwrite(STDOUT, 'Please input a argument:');// $response = trim(fgets(STDIN));// $this->send($_sock, $response);// echo "{$key} response to Client:".$response,"\n";}}}}}/*** 握手处理* @param $newClient socket* @return int 接收到的信息*/public function handshaking($newClient, $line){$headers = [];$lines = preg_split("/\r\n/", $line);foreach ($lines as $line) {$line = chop($line);if (preg_match('/\A(\S+): (.*)\z/', $line, $matches)) {$headers[$matches[1]] = $matches[2];}}$secKey = $headers['Sec-WebSocket-Key'];$secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));$upgrade ="HTTP/1.1 101 Web Socket Protocol Handshake\r\n" ."Upgrade: websocket\r\n" ."Connection: Upgrade\r\n" ."WebSocket-Origin: $this->address\r\n" ."WebSocket-Location: ws://$this->address:$this->port/websocket/websocket\r\n" ."Sec-WebSocket-Accept:$secAccept\r\n\r\n";return socket_write($newClient, $upgrade, strlen($upgrade));}/*** 解析接收数据* @param $buffer* @return null|string*/public function message($buffer){$len = $masks = $data = $decoded = null;$len = ord($buffer[1]) & 127;if ($len === 126) {$masks = substr($buffer, 4, 4);$data = substr($buffer, 8);} elseif ($len === 127) {$masks = substr($buffer, 10, 4);$data = substr($buffer, 14);} else {$masks = substr($buffer, 2, 4);$data = substr($buffer, 6);}for ($index = 0; $index < strlen($data); $index++) {$decoded .= $data[$index] ^ $masks[$index % 4];}return $decoded;}/*** 发送数据* @param $newClinet 新接入的socket* @param $msg 要发送的数据* @return int|string*/public function send($newClinet, $msg){$msg = $this->frame($msg);socket_write($newClinet, $msg, strlen($msg));}public function frame($s){$a = str_split($s, 125);if (count($a) == 1) {return "\x81" . chr(strlen($a[0])) . $a[0];}$ns = '';foreach ($a as $o) {$ns .= "\x81" . chr(strlen($o)) . $o;}return $ns;}/*** 关闭socket*/public function close(){return socket_close($this->_sockets);}
}$sock = new SocketService();
$sock->run();
?>
Unity 客户端:(Best HTTP/2 | Network | Unity Asset Store)依赖于BestHttp/2 v2.52版本
using BestHTTP.WebSocket;
using System;
using UniRx;
using UnityEngine;public class WebSocketTest : MonoBehaviour
{//公网// string address = "ws://xx.xx.xx.xx:12345/websockets.php";string address = "ws://127.0.0.1:12345/websockets.php";WebSocket webSocket;public void Start(){//Observable.EveryUpdate()// .Where(_ => Input.GetKeyDown(KeyCode.Space))// .Subscribe(_ =>// {// webSocket.Send("Unity Client!");// }).AddTo(this);Init();}public void Update(){if (Input.GetKeyDown(KeyCode.Space)){webSocket.Send("Unity Client!");}}public void Init(){if (webSocket == null){webSocket = new WebSocket(new Uri(address));//#if !UNITY_WEBGL
// webSocket.StartPingThread = true;
//#endif// Subscribe to the WS eventswebSocket.OnOpen += OnOpen;webSocket.OnMessage += OnMessageRecv;webSocket.OnBinary += OnBinaryRecv;webSocket.OnClosed += OnClosed;webSocket.OnError += OnError;// Start connecting to the serverwebSocket.Open();}}public void Destroy(){if (webSocket != null){webSocket.Close();webSocket = null;}}void OnOpen(WebSocket ws){Debug.Log("OnOpen: ");webSocket.Send("Unity Client!");}void OnMessageRecv(WebSocket ws, string message){Debug.LogFormat("OnMessageRecv: msg={0}", message);}void OnBinaryRecv(WebSocket ws, byte[] data){Debug.LogFormat("OnBinaryRecv: len={0}", data.Length);}void OnClosed(WebSocket ws, UInt16 code, string message){Debug.LogFormat("OnClosed: code={0}, msg={1}", code, message);webSocket = null;}void OnError(WebSocket ws, string reason){string errorMsg = string.Empty;
#if !UNITY_WEBGL || UNITY_EDITORif (ws.InternalRequest.Response != null){errorMsg = string.Format("Status Code from Server: {0} and Message: {1}", ws.InternalRequest.Response.StatusCode, ws.InternalRequest.Response.Message);}
#endifDebug.LogFormat("OnError: error occured: {0}\n", (reason != null ? reason : "Unknown Error " + errorMsg));webSocket = null;}
}
Cocos Creator:
// Learn TypeScript:
// - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
// - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
// - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.htmlconst {ccclass, property} = cc._decorator;@ccclass
export default class NewClass extends cc.Component {ws:WebSocket = null;start () {//局域网this.ws = new WebSocket("ws://127.0.0.1:12345/websockets.php");// 公网// this.ws = new WebSocket("ws://xxx.xx.xx.xx:12345/websockets.php");var self = this;// ws.send("0: Cocos Creator Client!");this.ws.onopen = function (evt) {console.log("Connection open ...");self.ws.send("0: Cocos Creator Client!");};this.ws.onmessage = function (evt) {console.log("Received Message: " + evt.data);//self.ws.close();};this.ws.onclose = function (evt) {console.log("Connection closed.");};// setTimeout(function () {// if (this.ws.readyState === WebSocket.OPEN) {// this.ws.send("Hello WebSocket, I'm a text message.");// }// else {// console.log("WebSocket instance wasn't ready...");// }// }, 3);cc.systemEvent.on('keydown', this.onKeyPress, this);}onKeyPress(e: cc.Event.EventKeyboard) {if (e.keyCode == cc.macro.KEY.space) {cc.log( "空格键按下");this.ws.send("0: Cocos Creator Client!");}}
}
这篇关于Unity CocosCreator PHP WebSocket 三方会谈的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!