Mega-Wechat is a service for sending WeChat template messages, implemented based on the Swoole network framework. It supports sending a large number of messages and executes the sending template message interface concurrently. The entire sending process is executed according to the queue on a first-come, first-served basis. Supports customized template messages, which can be changed and used at any time.
When operating in a company, we need to frequently send WeChat template messages to designated users. At that time, the implementation of other businesses is more urgent, so we just simply hardcode some template messages into the controller, and execute the commands to complete the operation requirements when using them. Therefore, when changing the template content, you need to change the code and update it with git. Moreover, due to the problem of single process, sending a large number of template messages will be very time-consuming (mainly due to the time-consuming time of curl calling the WeChat interface).
Several solutions came to mind for this:
The first method directly implements a multi-process client to call WeChat to send template messages API through curl. This method is simple and fast to implement, but it cannot support the needs of other businesses to call template messages.
The second method is to have one process distribute tasks and fork multiple sub-processes, and continuously poll the redis queue through the sub-processes. This solution is also relatively simple to implement, but the controllability is so poor that it is basically difficult to control.
The third solution, which is currently in use, is to use swoole to implement a service similar to a message queue. Multiple tasks perform slow curl operations to adjust the WeChat API, and the execution results can be returned to the client. Since swoole is a very powerful network framework and can receive a lot of concurrency, in theory, swoole can handle a large number of requests to send template messages. However, because WeChat’s sending template message API is relatively time-consuming, a large number of request delivery Execute in task because The processing speed is not as fast as the receiving speed, which will lead to buffer overflow. Therefore, Mega-Wechat uses a file queue to put all requests into the queue first. When the task process is idle, the requests are taken out of the queue and delivered. Go to the task to process the request to send the template message. Such an implementation will not cause buffer overflows and can support a large amount of concurrency. However, since WeChat has a set of rules and restrictions on template messages, a large number of API calls are only theoretical.
The Mega-Wechat system architecture is shown in the figure below:
System execution process description:
The above description is a synchronous process, which can be asynchronous or synchronous processing for the client.
config/ 服务器配置
libs/
Network/
Server/
Swoole/ Mega核心类库
Wechat/ 微信API
logs/
vendor/ 支持composer,依赖monolog写日志
autoload.php
mega Mega命令入口
first step To install PHP, version 5.6 or above is required. Because the server-side queue uses the SPL function and the syntax of PHP's new features
Step 2 Install Mysql, any version is fine.
yum install mysql
After successful installation, Mysql needs to create a mega_wechat_template table. The detailed structure is introduced in the next chapter.
Step 3 Before installing the swoole extension, you must ensure that the following software has been installed on the system
php-5.3.10 or higher gcc-4.4 or higher make autoconf
Download address
https://github.com/swoole/swoole-src/releases
http://pecl.php.net/package/swoole
http://git.oschina.net/matyhtf/swoole
After downloading the source code package, enter the source code directory in the terminal and execute the following commands to compile and install
cd swoole
phpize ./configure
make
make install
WeChat templates are stored in the Mega-Wechat server. This is because most businesses need to frequently modify the content of templates. For these templates that often need to be changed, it is very inconvenient if they are written into the program. Therefore, MySql is used to store the templates and add some additional fields required by the business.
For the server, the database template will be cached when it is started. If the template needs to be updated, there are corresponding commands to update the server's template cache in real time. Therefore, there is no need to worry about the need to obtain the template from the database every time the template is sent, resulting in performance degradation. question.
Table structure:
CREATE TABLE ` mega_wechat_template ` (
` tmpl_key ` char ( 32 ) NOT NULL COMMENT '模板key ' ,
` title ` varchar ( 100 ) NOT NULL DEFAULT ' ' COMMENT '模板标题' ,
` template ` text NOT NULL COMMENT '模板内容' ,
` created_at ` int ( 11 ) NOT NULL DEFAULT ' 0 ' ,
` updated_at ` int ( 11 ) NOT NULL DEFAULT ' 0 ' ,
PRIMARY KEY ( ` tmpl_key ` )
)
Field description:
Field | illustrate |
---|---|
tmpl_key | Template key (as a parameter for sending Mega template command request) |
title | Template title |
template | Template content, storage format is json |
created_at | creation time |
updated_at | Update time |
template字段格式,例子如下:
{
"touser" : " ${OPENID} " ,
"template_id" : " ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY " ,
"url" : " http://weixin.qq.com/download " ,
"data" :{
"first" : {
"value" : "恭喜你购买成功! " ,
"color" : " #173177 "
},
"keynote1" :{
"value" : "巧克力" ,
"color" : " #173177 "
},
"keynote2" : {
"value" : " 39.8元" ,
"color" : " #173177 "
},
"keynote3" : {
"value" : " 2014年9月22日" ,
"color" : " #173177 "
},
"remark" :{
"value" : "欢迎再次购买! " ,
"color" : " #173177 "
}
}
}
注意:JSON中的${OPENID},是自定义的变量,调用微信模板消息接口前会先解析json模板并替换相应的自定义变量。
该变量由发送Mega模板命令请求的参数定义
The configuration files are uniformly placed in the config directory, and each server has an independent configuration.
[server]
;启动server类
class = " ServerMegaWechatServer "
;协议类
protocol = " NetworkMegaWechatProtocol "
;主机和端口
listen[] = 127.0.0.1:9501
;缓存模板个数
table_size = 100 ;
;缓存模板内容最大size
template_size = 4048
;文件队列存储路径
queue_file_path = " /Mega-Wechat/logs/queue "
[setting]
; ;;;;;;;;;;;swoole配置;;;;;;;;;;;;;;
dispatch_mode = 2
worker_num = 2
task_worker_num = 8
open_eof_check = true
package_length_type = N
package_length_offset = 0
package_body_offset = 4
package_max_length = 2465792
daemonize = 1
; ;swoole_log文件
; log_file = "/qcloud/logs/swoole.log"
[pdo]
dsn = " mysql:host=127.0.0.1;dbname=mega "
username = root
password = i201314
table_prefix = mega_
[wechat]
app_id = wx10c4b54cf0aae125
app_secret = e01207cc547f62d73f5099aae83a9f15
token = e01207cd547f62d73f5099cae83a9f15
[log]
; ;;;;;系统log配置,基于monolog;;;;;;
log_file = /Mega-Wechat/logs/mega.log
;存储日志级别
log_level = warning
;日志前缀
log_prefix = mega
Start the server according to the configuration file, using each .ini file as the service name and configuration, such as the config/wechat.ini configuration file:
cd Mega-Wechat
//php mega ${配置文件名} ${cmd}
php mega wechat start //开启服务
php mega wechat stop //关闭服务
php mega wechat restart //重启服务
Mega-Wechat uses TCP for communication, and the protocol adopts a fixed header + packet body protocol design. The general protocol format is as follows:
{packLength}{headerLength}{command} {params}{opaque}{bodyLength}{body}
Note: the spaces between {command} {params}, each params parameter is separated by spaces.
Send template message command protocol, each command represents a WeChat template message sending. The client sends a Send command to the server, which will execute the WeChat template message API once and then respond to the client with the result and return an ACK confirmation.
The corresponding class is: NetworkSendCommand
/**
* @param $opaque int 发送序号
* @param $openid string 微信openid
* @param $key string 模板key
* @param $data array 自定义变量,可选,默认为null,例子如下:
* 传入数组为:['mega' => 'wechat']
* 模板内容中包含一个${mega}自定义变量,则数组中的mega值会替换到相应变量中。
* @param $fd int 客户端标志,可选,默认为null
*/
new SendCommand ( $ opaque , $ openid , $ key , $ data , $ fd )
Template message enqueuing command protocol. After receiving the command, the server will immediately join the queue and respond with ACK confirmation. Subsequently, it will execute the WeChat template message processing after queuing according to the queue.
The corresponding class is: NetworkPushCommand
/**
* @param $opaque int 发送序号
* @param $openid string 微信openid
* @param $key string 模板key
* @param $data array 自定义变量,可选
*/
new PushCommand ( $ opaque , $ openid , $ key , $ data )
Set template caching command protocol. After receiving this command, the server will obtain the template content from the database according to the key and cache it in the memory. If the key does not exist or exceeds the cache size, it will respond with relevant error messages.
The corresponding class is: NetworkSetTableCommand
/**
* @param $opaque int 发送序号
* @param $key string 模板key
* @param $fd int 客户端标志,客户端发送命令时可为null
*/
new SetTableCommand ( $ opaque , $ key , $ fd )
General response command protocol, returns the request result. This protocol can be used as an ACK confirmation and as a response to the last request based on the returned opaque value. The returned code is used as a response code, using the same semantics as the HTTP protocol response status code. If the response is an error, the message field will usually be included. For example, if the Send command fails to be sent, the response code will be 400, and the message will be the json returned by the WeChat template message interface as the response.
The corresponding class is: NetworkBooleanCommand
/**
* @param $code int 应答状态码
* @param $message string 消息内容
* @param $opaque int 应答序号
*/
new BooleanCommand ( $ code , $ message , $ opaque )
The first is to use the Send protocol, and the other is the Push protocol, both of which can cope with different scenarios.
The Push protocol is mainly used for implementations that do not want to wait for WeChat to call the API. Specifically, Push will put each template message into the queue, and the server will respond immediately. At this time, the client can continue to run the business logic without caring about whether the template message is successful. (The server side can guarantee to consume this message)
The Send protocol also sends template messages. Unlike Push, the server will respond with the result after calling the WeChat template message API. After receiving the response, the client can obtain the sent result (the response is the Result protocol, the code returned is 200 if successful, and the code 400 is returned if failed, and the message is the json of the result returned by WeChat). Based on the result, the client can do the corresponding business. Logical processing.
There are several problems with the Send protocol:
Compared with the above issues, the advantage of this protocol is that it can know the result of sending, and can control the business logic of whether to continue sending the next message.
Actual scenario: If you need to send template messages in batches to a specified group of users or all users, you can use this protocol to achieve this. Sending a batch of template messages to users can be regarded as a task. The task contains data such as the number of messages sent, the number of successes, the number of failures, the template key, etc. The business logic of sending, receiving and recording the sending process is implemented through the client. Each server response is used as the basis for success or failure of the update. The specific business process is as follows:
It is recommended to use the Swoole asynchronous client to implement the above business logic, and after running, the client can be run in the background as a daemon process, and can be closed with kill when needed.
Attached is a client implementation rendering:
Finally, the open source Client DEMO github is attached: https://github.com/imRainChen/Mega-WeChat-Client
If you have any suggestions, please feel free to contact us, and you can also post questions and feedback.
Email: [email protected]
Apache License Version 2.0 see http://www.apache.org/licenses/LICENSE-2.0.html