问题描述
在Azure App Service中,有对.Net,Java的WebSocket支持的示例代码,但是没有成功的PHP代码。 以下的步骤则是如何基于Azure App Service实现PHP版的websocket。
实现步骤
参考PHP代码链接:(GitHub:https://github.com/ghedipunk/PHP-Websockets, 本地博客园:https://www.cnblogs.com/lulight/articles/13787309.html)。但由于这一示例代码中有些错误,所以需要修改部分代码
1) 新加 web.config 文件,配置httpplatformhandler及websocket的启动路径文件。
<?xml version="1.0" encoding="UTF-8"?> <configuration> <system.webServer> <webSocket enabled="true" /> <handlers> <add name="httpplatformhandler" path="*.php" verb="*" modules="httpPlatformHandler" resourceType="Unspecified"/> </handlers> <httpPlatform processPath="D:Program Files (x86)PHPv7.4php.exe" arguments="D:homesitewwwroot estwebsock.php" stdoutLogEnabled="true" stdoutLogFile="D:homeLogFilesphp-log.txt"> </httpPlatform> </system.webServer> </configuration>
2)修改文件testwebsock.php中的内容,$echo = new echoServer("0.0.0.0",getenv("HTTP_PLATFORM_PORT"),1048576); 端口号设置在应用配置参数HTTP_PLATFORM_PORT中。
#!/usr/bin/env php <?php require_once('./websockets.php'); class echoServer extends WebSocketServer { function __construct($addr, $port, $bufferLength) { parent::__construct($addr, $port, $bufferLength); $this->userClass = 'MyUser'; } //protected $maxBufferSize = 1048576; //1MB... overkill for an echo server, but potentially plausible for other applications. protected function process ($user, $message) { $this->send($user,$message); } protected function connected ($user) { // Do nothing: This is just an echo server, there's no need to track the user. // However, if we did care about the users, we would probably have a cookie to // parse at this step, would be looking them up in permanent storage, etc. } protected function closed ($user) { // Do nothing: This is where cleanup would go, in case the user had any sort of // open files or other objects associated with them. This runs after the socket // has been closed, so there is no need to clean up the socket itself here. } } $echo = new echoServer("0.0.0.0",getenv("HTTP_PLATFORM_PORT"),1048576); try { $echo->run(); } catch (Exception $e) { $echo->stdout($e->getMessage()); }
3)将client.html 中server URL(var host = "ws://<your web site name>.chinacloudsites.cn/index.php";)改写为对应的website name。
<html><head><title>WebSocket</title> <style type="text/css"> html,body { font:normal 0.9em arial,helvetica; } #log { width:600px; height:300px; border:1px solid #7F9DB9; overflow:auto; } #msg { width:400px; } </style> <script type="text/javascript"> var socket; function init() { var host = "ws://xxxxxxxx.chinacloudsites.cn/index.php"; // SET THIS TO YOUR SERVER try { socket = new WebSocket(host); log('WebSocket - status '+socket.readyState); socket.onopen = function(msg) { log("Welcome - status "+this.readyState); }; socket.onmessage = function(msg) { log("Received: "+msg.data); }; socket.onclose = function(msg) { log("Disconnected - status "+this.readyState); }; } catch(ex){ log(ex); } $("msg").focus(); } function send(){ var txt,msg; txt = $("msg"); msg = txt.value; if(!msg) { alert("Message can not be empty"); return; } txt.value=""; txt.focus(); try { socket.send(msg); log('Sent: '+msg); } catch(ex) { log(ex); } } function quit(){ if (socket != null) { log("Goodbye!"); socket.close(); socket=null; } } function reconnect() { quit(); init(); } // Utilities function $(id){ return document.getElementById(id); } function log(msg){ $("log").innerHTML+="<br>"+msg; } function onkey(event){ if(event.keyCode==13){ send(); } } </script> </head> <body onload="init()"> <h3>WebSocket v2.00</h3> <div id="log"></div> <input id="msg" type="textbox" onkeypress="onkey(event)"/> <button onclick="send()">Send</button> <button onclick="quit()">Quit</button> <button onclick="reconnect()">Reconnect</button> </body> </html>
4) 添加websocket拓展,早D:homesite 路径下添加ini文件夹,并在里面添加一个文件名为php.ini文件,内容如下:
[ExtensionList] extension=sockets
然后,ini和wwwroot文件夹在kudu站点中的相对位置如下图所示:(必须步骤,非常重要)
5)在App Service门户中配置应用参数,PHP_INI_SCAN_DIR="D:homesiteini"。 效果如下:
以上步骤完成后,就可以访问站点下的client.html测试页面,验证此次配置是否成功:
在以上的过程中,必须在App Service的配置页面中启用Web Socket功能。
参考资料
PHP WebSockets:https://github.com/ghedipunk/PHP-Websockets