1. 程式人生 > >websocket服務端PHP程式碼

websocket服務端PHP程式碼

在網上看到一個高手寫的PHP程式碼就直接拉下來修改了一下,原貼地址暫時沒找到,找到了貼回來
2016年6月18日
這位大佬寫的很詳細,看他的部落格會好一點
http://blog.jnecw.com/p/1523

//socket.php
set_time_limit(0);//永不超時
class socket{
    private $host = '127.0.0.1';
    private $port = 8080;
    private $maxuser = 10;
    public  $accept = array(); //連線的客戶端
    private $cycle = array(); //迴圈連線池
private $isHand = array();//握手資訊 //載入socket配置 function __construct($host, $port, $max) { $this->host = $host; $this->port = $port; $this->maxuser = $max; } //掛起socket public function start_server() { //建立一個socket $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //配置socket
socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, TRUE); //繫結介面,最多10個人連線,超過的客戶端連線會返回WSAECONNREFUSED錯誤 socket_bind($this->socket, $this->host, $this->port); //監聽介面 socket_listen($this->socket, $this->maxuser); while(TRUE) { //獲取所有socket連線
$this->cycle = $this->accept; $this->cycle[] = $this->socket; //阻塞用,有新連線時才會結束 socket_select($this->cycle, $write, $except, null); foreach ($this->cycle as $k => $v) { //當socket執行到連線池最後一位時,開始新增連線 if($v === $this->socket) { //如果socket連線失敗,跳出本次迴圈 if (($accept = socket_accept($v)) < 0) { continue; } //連線成功加入連線池 $this->add_accept($accept); continue; } //在連線池中搜索socket連線ID $acceptId = array_search($v, $this->accept); //如果連線沒有儲存至連線池,跳出本次迴圈 if ($acceptId === NULL) { continue; } //沒訊息的socket就斷開 if ([email protected]_recv($v, $data, 1024, 0) || !$data) { $this->close($v); continue; } //檢查是否握手 if (!$this->isHand[$acceptId]) { //進行握手 $this->upgrade($v, $data, $acceptId); continue; } //將資料進行解碼 $data = $this->decode($data); //將資訊返回給客戶端 $this->send_to_user($v,$data); } sleep(1); } } /** * 新建一個連線 * @param $accept 套接號 */ private function add_accept($accept) { $this->accept[] = $accept; $accept = array_keys($this->accept); //獲取新連線的key值,用於跟握手資訊繫結 $acceptId = end($accept); //新增初次連線使用者握手資訊 $this->isHand[$acceptId] = FALSE; } /** * 關閉一個連線 * @param $accept 套接號 */ private function close($accept) { //在連線池中搜索套接號 $acceptId = array_search($accept, $this->accept); //斷開socket連線 socket_close($accept); //銷燬變數 unset($this->cycle[$acceptId]); unset($this->accept[$acceptId]); unset($this->isHand[$acceptId]); } /** * 響應升級協議,與websocket進行握手 * @param $accept 套接號 * @param $data websocket傳送的資料 * @param $acceptId 與套接號繫結的Id */ private function upgrade($accept, $data, $acceptId) { //用正則表示式獲取websocket傳輸過來的key值 if (preg_match("/Sec-WebSocket-Key: (.*)\r\n/",$data,$match)) { //服務端生成對應key值返回 $key = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); $upgrade = "HTTP/1.1 101 Switching Protocol\r\n" . "Upgrade: websocket\r\n" . "Connection: Upgrade\r\n" . "Sec-WebSocket-Accept: " . $key . "\r\n\r\n"; //必須以兩個回車結尾 //向套介面寫入資料 socket_write($accept, $upgrade, strlen($upgrade)); $this->isHand[$acceptId] = TRUE; } } /** * 編碼資訊 * @param $data 需要編碼的資料 */ private function frame($data){ //將資料轉為陣列,一個元素長度最高為125 $array = str_split($data, 125); //新增標頭檔案資訊,不然前臺無法接受 if (count($array) == 1){ return "\x81" . chr(strlen($array[0])) . $array[0]; } $ns = ""; foreach ($data as $v){ $ns .= "\x81" . chr(strlen($v)) . $v; } return $ns; } /** * 按照websocket協議進行解碼 * @param $buffer 需要解碼的資料 */ private function decode($buffer) { $len = $masks = $data = $decoded = null; //獲取傳遞過來資料長度 $len = ord($buffer[1]) & 127; if ($len === 126) { $masks = substr($buffer, 4, 4); $data = substr($buffer, 8); } else if ($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; } /** * 向所有連線至socket的使用者傳送訊息 * @param $accept 套接號 * @param $data 傳送的資料 */ private function send_to_user($accept, $data){ //新增標頭檔案資訊 $data = $this->frame($data); socket_write($accept, $data, strlen($data)); } }

如何呼叫

//index.php
require('socket.php');
//設定連線資訊
$ws = new socket('192.168.0.114', '8080', 10);
//開啟socket服務端
$ws->start_server();

用命令列開啟index.php就可以掛起socket伺服器了
這裡寫圖片描述

相關推薦

websocket服務PHP程式碼

在網上看到一個高手寫的PHP程式碼就直接拉下來修改了一下,原貼地址暫時沒找到,找到了貼回來 2016年6月18日 這位大佬寫的很詳細,看他的部落格會好一點 http://blog.jnecw.com/p/1523 //socket.php set_tim

.NET 即時通信,WebSocket服務實例

轉發 dev 技術分享 用戶添加 for tle .so 正在 utf-8 即時通信常用手段 1.第三方平臺 谷歌、騰訊 環信等多如牛毛,其中谷歌即時通信是免費的,但免費就是免費的並不好用。其他的一些第三方一般收費的,使用要則限流(1s/限制x條消息)要麽則限制用戶數。 但

NodeJs服務除錯程式碼

1、使用console.log(); 在需要除錯的程式碼前加上改語句能夠在控制檯打印出結果 2、在vscode中進行nodejs服務端程式碼除錯(程式碼修改自動重啟服務端) 使用到的是nodemon,具體在package.json檔案中配置如下: "scripts": {

websocket 服務(tornado)

import tornado.ioloop import tornado.web import tornado.websocket from tornado.options import define, options, parse_command_line from tornado import

SpringBoot 整合 Tomcat 的 WebSocket 服務

傳統 Tomcat 開發 WebSocket 回顧      WebSocket 的出現是基於 Web 應用的實時性需要而產生的,在淘寶、京東等網頁客服、網頁賣家聊天等需求上應用廣泛。對於前端網頁可以使用 H5 開發 WebSocket 客戶端,也可以使用 

支付寶支付-服務php對接移動應用app

準備工作 一、建立應用 1、要在支付寶開放平臺那裡建立自己的應用,建立這裡我簡單描述一下,更詳細的還是官方文件! 2、把裡面的資訊填完,提交稽核(稽核時間大概一天) 3、稽核完了,在應用那裡拿到APPID,把AppId記下來,然後

TCP 客戶 服務詳細程式碼

轉自:http://www.myexception.cn/program/1912019.html TCP網路程式設計中connect()、listen()和accept()三者之間的關係 基於 TCP 的網路程式設計開發分為伺服器端和客戶端兩部分,常見的核心步驟和流程如

html 提交表單,圖片和文字一起提交,圖片存入伺服器,圖片地址和表單資訊存入資料庫,帶後php程式碼

html <!DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no

一個用python寫的websocket服務

由於要在頁面上呼叫後臺的一個shell程式,但是這個shell執行時間很長,如果非同步獲取shell的輸出?而不必漫長的等待shell執行完畢才會一下把資料全部輸出? 我們知道原生的http協議不可能完成這個要求,除非你把輸出更新到一個文本里,然後用js倫詢去取,這不扯淡嗎

2、netty3服務入門程式碼示例

package com.server; import java.net.InetSocketAddress; import java.util.concurrent.ExecutorService; import java.util.concurrent.Ex

加密解密演算法,客戶C++加密,服務PHP解密

這裡有兩個我之前經常用的加密/解密的字串函式: /** * 可逆的字串加密函式 * @param int $txtStream 待加密的字串內容 * @param int $password 加密密碼 * @return string 加密後的字串 */ public

go:搭建WebSocket服務

原帖;http://www.jb51.net/article/110276.htm //WebSoketDemo01 package main import ("fmt""log""net/http""golang.org/x/net/websocket" ) func E

C# 實現WebSocket服務

.net4.5中實現了對websocket的支援 在這裡我使用的是.net4.0。因此需要對原本的socket傳送的資料根據websocket的協議進行解析和打包。 文章參考 http://www.cnblogs.com/dolphinX/p/3462898.h

websocket 服務

1、引入 tyrus-standalone-client-1.13.1.jar 包2、import java.io.IOException; import javax.websocket.OnClose; import javax.websocket.OnError; im

.NET 即時通訊,WebSocket服務例項

即時通訊常用手段 1.第三方平臺 谷歌、騰訊 環信等多如牛毛,其中谷歌即時通訊是免費的,但免費就是免費的並不好用。其他的一些第三方一般收費的,使用要則限流(1s/限制x條訊息)要麼則限制使用者數。 但穩定性什麼都還不錯,又能將服務壓力甩出 2.System.Net.Sock

springboot搭建WebSocket服務

基於springboot框架編寫一個WebSocket服務端,並通過簡單的html介面模擬客戶端驗證服務端連線。 1、pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http:

netty的websocket服務開發

前兩篇文章分析了node.js版本的socket.io的服務端與客戶端的程式碼,其實他們socket.io就是在websocket的基礎上進一步做了一層封裝,添加了一些心跳,重連線。。。 這篇文章就先來看看在netty中是如何建立websocket服務端的吧,先來回顧一下w

用nodejs快速實現微信小程式的websocket服務

摘要: 微信小程式服務端使用websocket方式。socket.io已作為nodejs體系中被廣泛應用的websocket解決方案,卻因socket.io對websocket做了高階封裝,不能相容微信小程式所採用的websocket標準協議無法直接使用,此外微

java-websocket 服務 開發中遇到的問題

一、     由於專案需求,需要早android裝置上架一個websocket服務,可以供瀏覽器呼叫。但是移動裝置的ip是不固定的,也就是說到作為服務端,移動裝置並不能完全滿足客戶端的需要。後來想到了用一臺中轉伺服器,在這臺伺服器上架上websocket服務,然而移動端和p

蘋果推送服務java 程式碼簡解

思路: 從客戶端獲取的deviceToken,定義訊息模式Payload,註冊deviceToken,連線APNS,傳送推送,停止連線APNS,刪除deviceToken; 1,從客戶端獲取的deviceToken,在此為了測試簡單,寫固定的一個測試裝置標識 String