liangl 11 vuotta sitten
vanhempi
commit
58d152cdfd

+ 36 - 0
applications/FileReceiverDemo/ClientDemo.php

@@ -0,0 +1,36 @@
+<?php
+if(!isset($argv[1]))
+{
+    exit("usage php ClientDemo.php file_path file_type\n");
+}
+
+$file_path = $argv[1];
+if(!is_file($file_path))
+{
+    exit("can not found $file_path\n");
+}
+
+// messge_type
+$file_type = isset($argv[2]) && $argv[2] > 0 ? (int)$argv[2] : 0;
+
+if(false === ($file_bin_data = file_get_contents($file_path)))
+{
+    exit("can not get contents of $file_path\n");
+}
+
+$address = "tcp://127.0.0.1:2015";
+if(!($sock = stream_socket_client($address, $err_no, $err_str)))
+{
+    exit("can not connect to $address $err_str");
+}
+
+$head_len = 5;
+$message_buffer = pack("NC", $head_len+strlen($file_bin_data), $file_type).$file_bin_data;
+
+fwrite($sock, $message_buffer);
+
+$recv_buffer = fread($sock, 65535);
+
+$recv_buffer_data = unpack("Nmessage_len/Cmessage_type", $recv_buffer);
+$recv_buffer_data['body']=substr($recv_buffer, $head_len);
+var_export($recv_buffer_data);

BIN
applications/FileReceiverDemo/workerman.png


+ 18 - 0
conf/conf.d/FileReceiverDemo.conf

@@ -0,0 +1,18 @@
+;监听ip及端口
+listen = tcp://0.0.0.0:2015
+;是否需要长连接 看自己应用场景
+persistent_connection = 1
+;启动多少进程
+start_workers=5
+;以哪个用户运行这个worker进程,需要root权限
+user=www-data
+;预读长度 unsigned int + unsigned char 共5字节
+preread_length=5
+
+;==以下是自定义的配置==
+;如果worker进程1分钟内退出max_worker_exit_count次则触发告警
+max_worker_exit_count=2000
+;每个worker进程最大内存阈值,超过这个值安全重启这个进程
+max_mem_limit=124000
+;telnet密码
+password=yourpassword

+ 1 - 1
man/Core/Lib/Checker.php

@@ -197,7 +197,7 @@ class Checker
             }
             if(0 != self::checkSyntaxError($worker_file, $class_name))
             {
-                unset(Config::instance()->config[$worker_name]);
+                //unset(Config::instance()->config[$worker_name]);
                 \Man\Core\Master::notice("$worker_name has Fatal Err");
                 echo"\033[31;40m [Fatal Err] \033[0m\n";
                 continue;

+ 87 - 0
workers/FileReceiverDemo.php

@@ -0,0 +1,87 @@
+<?php 
+require_once WORKERMAN_ROOT_DIR . 'man/Core/SocketWorker.php';
+/**
+ * 二进制协议,接收文件demo
+ * @author walkor <worker-man@qq.com>
+ */
+class FileReceiverDemo extends Man\Core\SocketWorker
+{
+    /**
+     * message_type 到 后缀名的映射
+     * @var array
+     */
+    protected static $fileTypeMap = array(
+        1 => 'jpg',
+        2 => 'png',
+        3 => 'gif',
+        4 => 'mp3',
+    );
+    
+    /**
+     * 确定包是否完整
+     * 二进制协议
+     * buffer
+     * {
+     *     unsigned int message_len;           // 整个包的长度
+     *     unsigned char message_type;         // 消息类型 自己定义 如:1图片数据 2声音数据....
+     *     char[message_len - 5] message_body; // 这部分是文件原始二进制数据
+     * }
+     * @see Worker::dealInput()
+     */
+    public function dealInput($buffer)
+    {
+        // 已经接收到的数据的长度
+        $recv_len = strlen($buffer);
+        // unsigned int + unsigned char 共5字节
+        $head_len = 5;
+        // 数据头没接收全?,继续接收
+        if($recv_len < $head_len)
+        {
+            return $head_len - $recv_len;
+        }
+        // 根据message_len判断当前数据是否接收完毕
+        $message_data = unpack("Nmessage_len/Cmessage_type", $buffer);
+        $message_len = $message_data['message_len'];
+        $message_type = $message_data['message_type'];
+        // 数据没接收完,继续接收$message_len - $recv_len 字节
+        if($message_len > $recv_len)
+        {
+            return $message_len - $recv_len;
+        }
+        // 数据接收完毕
+        return 0;
+    }
+    
+    /**
+     * 处理业务
+     * @see Worker::dealProcess()
+     */
+    public function dealProcess($buffer)
+    {
+        // unsigned int + unsigned char 共5字节
+        $head_len = 5;
+        // 解包
+        $message_data = unpack("Nmessage_len/Cmessage_type", $buffer);
+        $message_len = $message_data['message_len'];
+        $message_type = $message_data['message_type'];
+        // 获得文件二进制数据
+        $file_bin_buffer = substr($buffer, $head_len, $message_len - $head_len);
+        // 保存数据到/tmp/workerman.recv.xxxxx
+        file_put_contents('/tmp/workerman.recv.'.time().'.'.self::getExt($message_type), $file_bin_buffer);
+        // 回复客户端 成功
+        $response_message_body = "上传成功";
+        // 255表示回包
+        $response_message_type = 255;
+        $this->sendToClient(pack("NC", $head_len+strlen($response_message_body), $response_message_type).$response_message_body);
+    }
+    
+    /**
+     * 根据message_type获得文件后缀
+     * @param int $message_type
+     * @return string  如:jpg gif ...
+     */
+    protected static function getExt($message_type)
+    {
+        return isset(self::$fileTypeMap[$message_type]) ? self::$fileTypeMap[$message_type] : 'unknown';
+    }
+}