| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- <?php
- $server = stream_socket_server("tcp://0.0.0.0:8000", $errno, $errstr);
- if (!$server) {
- die("Error: $errstr ($errno)");
- }
- function send_sse($client, $id, $event, $data, $retry = 3000) {
- $sseData = "id: $id\n";
- $sseData .= "event: $event\n";
- $sseData .= "data: " . json_encode($data) . "\n";
- $sseData .= "retry: $retry\n\n"; // The retry comment is optional and should follow client's needs
-
- fwrite($client, $sseData);
- fflush($client);
- }
- while ($client = @stream_socket_accept($server)) {
- // 读取请求
- $request = fread($client, 1024);
- list($headers, $body) = explode("\r\n\r\n", $request, 2);
- // 简单解析请求头
- $headerLines = explode("\r\n", $headers);
- $requestLine = array_shift($headerLines);
- preg_match('/\btimeout:\s*true\b/i', $headers, $timeoutMatch);
- preg_match('/\b(bodytype):[ ]*([\w\d]+)\b/i', $headers, $bodyTypeMatch);
- $bodyType = $bodyTypeMatch[2] ?? null;
- preg_match('/^(GET|POST|PUT|DELETE)\s(\/\S*)\sHTTP\/1.1/', $requestLine, $matches);
- $method = $matches[1];
- $path = $matches[2];
- $headerAssoc = [];
-
- foreach ($headerLines as $header) {
- list($name, $value) = explode(": ", $header, 2);
- $headerAssoc[strtolower($name)] = $value;
- }
- if (substr($path, 0, 4) === '/sse') {
- $responseHeaders = "HTTP/1.1 200 OK\r\n" .
- "Content-Type: text/event-stream;charset=UTF-8\r\n" .
- "Cache-Control: no-cache\r\n" .
- "Connection: keep-alive\r\n";
- foreach ($headerAssoc as $name => $value) {
- $responseHeaders .= $name . ": " . $value . "\r\n";
- }
- $responseHeaders .= "\r\n";
- fwrite($client, $responseHeaders);
- // 刷新缓冲区,确保头部被立刻发送
- flush();
- // 模拟发送事件流
- $count = 0;
- while ($count < 5) {
- $data = [
- "count" => $count
- ];
- $sseData = "id: sse-test\n";
- $sseData .= "event: flow\n";
- $sseData .= "data: " . json_encode($data) . "\n";
- $sseData .= "retry: 3000\n\n"; // 重试时间可选
- fwrite($client, $sseData);
- // 再次刷新缓冲区,以确保数据被发送
- flush();
- // 等待100毫秒
- usleep(100000);
- $count++;
- }
- fclose($client);
- continue;
- }
- if ($timeoutMatch) {
- // 模拟超时
- sleep(5);
- $responseHeaders = "HTTP/1.1 500 Internal Server Error\r\n" .
- "Content-Type: text/plain\r\n" .
- "Connection: close\r\n\r\n";
- fwrite($client, $responseHeaders . "Server Timeout");
- } else {
- $headerAssoc = [];
- foreach ($headerLines as $headerLine) {
- list($key, $value) = explode(': ', $headerLine, 2);
- $headerAssoc[strtolower($key)] = trim($value);
- }
- // 获取路径和请求方法
- preg_match('/^(GET|POST|PUT|DELETE)\s(\/\S*)\sHTTP\/1.1/', $requestLine, $matches);
- $method = $matches[1];
- $path = $matches[2];
- // 构建响应头
- $responseHeaders = "HTTP/1.1 200 OK\r\n" .
- "Connection: close\r\n" .
- "Content-Type: application/json\r\n" .
- "x-acs-request-id: A45EE076-334D-5012-9746-A8F828D20FD4\r\n" .
- "http-method: $method\r\n" .
- "pathname: $path\r\n" .
- "raw-body: $body\r\n";
- // 构建响应体
- $responseBody = "";
- echo $bodyType."\n";
- switch ($bodyType) {
- case 'array':
- $responseBody = json_encode(["AppId", "ClassId", "UserId"]);
- break;
- case 'error':
- $responseHeaders = "HTTP/1.1 400 Bad Request\r\n" .
- "Connection: close\r\n" .
- "Content-Type: application/json\r\n" .
- "x-acs-request-id: A45EE076-334D-5012-9746-A8F828D20FD4\r\n" .
- "http-method: $method\r\n" .
- "pathname: $path\r\n";
- $responseBody = json_encode([
- "Code" => "error code",
- "Message" => "error message",
- "RequestId" => "A45EE076-334D-5012-9746-A8F828D20FD4",
- "Description" => "error description",
- "AccessDeniedDetail" => new stdClass()
- ]);
- break;
- case 'error1':
- $responseHeaders = "HTTP/1.1 400 Bad Request\r\n" .
- "Connection: close\r\n" .
- "Content-Type: application/json\r\n" .
- "x-acs-request-id: A45EE076-334D-5012-9746-A8F828D20FD4\r\n" .
- "http-method: $method\r\n" .
- "pathname: $path\r\n";
- $responseBody = json_encode([
- "Code" => "error code",
- "Message" => "error message",
- "RequestId" => "A45EE076-334D-5012-9746-A8F828D20FD4",
- "Description" => "error description",
- "AccessDeniedDetail" => new stdClass(),
- "accessDeniedDetail" => ["test" => 0]
- ]);
- break;
- case 'error2':
- $responseHeaders = "HTTP/1.1 400 Bad Request\r\n" .
- "Connection: close\r\n" .
- "Content-Type: application/json\r\n" .
- "x-acs-request-id: A45EE076-334D-5012-9746-A8F828D20FD4\r\n" .
- "http-method: $method\r\n" .
- "pathname: $path\r\n";
- $responseBody = json_encode([
- "Code" => "error code",
- "Message" => "error message",
- "RequestId" => "A45EE076-334D-5012-9746-A8F828D20FD4",
- "Description" => "error description",
- "accessDeniedDetail" => ["test" => 0]
- ]);
- break;
- default:
- $responseBody = json_encode([
- "AppId" => "test",
- "ClassId" => "test",
- "UserId" => 123
- ]);
- }
- fwrite($client, $responseHeaders . "\r\n" . $responseBody);
- }
- fclose($client);
- continue;
- }
- fclose($server);
|