Mega-Wechat es un servicio para enviar mensajes de plantilla WeChat, implementado en base al marco de red Swoole. Admite el envío de una gran cantidad de mensajes y ejecuta la interfaz de mensajes de plantilla de envío al mismo tiempo. Todo el proceso de envío se ejecuta de acuerdo con la cola por orden de llegada. Admite mensajes de plantilla personalizados, que se pueden cambiar y utilizar en cualquier momento.
Cuando operamos en una empresa, necesitamos enviar con frecuencia mensajes de plantilla de WeChat a usuarios designados. En ese momento, la implementación de otras empresas es más urgente, por lo que simplemente codificamos algunos mensajes de plantilla en el controlador y ejecutamos los comandos para completar el proceso. requisitos de operación al usarlos. Por lo tanto, al cambiar el contenido de la plantilla, debe cambiar el código y actualizarlo con git. Además, debido al problema del proceso único, enviar una gran cantidad de mensajes de plantilla llevará mucho tiempo (principalmente debido al tiempo). Consumiendo tiempo de curl llamando a la interfaz WeChat).
Se me ocurrieron varias soluciones para esto:
El primer método implementa directamente un cliente multiproceso para llamar a WeChat y enviar mensajes de plantilla API a través de curl. Este método es simple y rápido de implementar, pero no puede satisfacer las necesidades de otras empresas para llamar mensajes de plantilla.
El segundo método es hacer que un proceso distribuya tareas y bifurque múltiples subprocesos, y sondee continuamente la cola de redis a través de los subprocesos. Esta solución también es relativamente simple de implementar, pero la controlabilidad es tan pobre que básicamente es difícil de implementar. control.
La tercera solución, actualmente en uso, es usar swoole para implementar un servicio similar a una cola de mensajes. Múltiples tareas realizan operaciones de curl lentas para ajustar la API de WeChat y los resultados de la ejecución se pueden devolver al cliente. Dado que swoole es un marco de red muy poderoso y puede recibir mucha concurrencia, en teoría, swoole puede manejar una gran cantidad de solicitudes para enviar mensajes de plantilla. Sin embargo, debido a que la API de envío de mensajes de plantilla de WeChat consume relativamente tiempo, una gran cantidad de. solicitar entrega Ejecutar en tarea porque La velocidad de procesamiento no es tan rápida como la velocidad de recepción, lo que provocará un desbordamiento del búfer. Por lo tanto, Mega-Wechat utiliza una cola de archivos para colocar todas las solicitudes en la cola primero. Cuando el proceso de la tarea está inactivo, las solicitudes se eliminan. la cola y entregado. Vaya a la tarea para procesar la solicitud para enviar el mensaje de plantilla. Esta implementación no provocará desbordamientos del búfer y puede admitir una gran cantidad de concurrencia. Sin embargo, dado que WeChat tiene un conjunto de reglas y restricciones sobre los mensajes de plantilla, una gran cantidad de llamadas API son solo teóricas.
La arquitectura del sistema Mega-Wechat se muestra en la siguiente figura:
Descripción del proceso de ejecución del sistema:
La descripción anterior es un proceso sincrónico, que puede ser un procesamiento asincrónico o sincrónico para el cliente.
config/ 服务器配置
libs/
Network/
Server/
Swoole/ Mega核心类库
Wechat/ 微信API
logs/
vendor/ 支持composer,依赖monolog写日志
autoload.php
mega Mega命令入口
primer paso Para instalar PHP, se requiere la versión 5.6 o superior. Porque la cola del lado del servidor utiliza la función SPL y la sintaxis de las nuevas funciones de PHP.
Paso 2 Instale Mysql, cualquier versión está bien.
mmm instalar mysql
Después de una instalación exitosa, Mysql necesita crear una tabla mega_wechat_template. La estructura detallada se presenta en el siguiente capítulo.
Paso 3 Antes de instalar la extensión swoole, debe asegurarse de que se haya instalado el siguiente software en el sistema
php-5.3.10 o superior gcc-4.4 o superior hacer autoconf
Descargar dirección
https://github.com/swoole/swoole-src/releases
http://pecl.php.net/package/swoole
http://git.oschina.net/matyhtf/swoole
Después de descargar el paquete de código fuente, ingrese el directorio del código fuente en la terminal y ejecute los siguientes comandos para compilar e instalar
lana de cd
phpize ./configurar
hacer
hacer instalar
Las plantillas de WeChat se almacenan en el servidor Mega-Wechat. Esto se debe a que la mayoría de las empresas necesitan modificar con frecuencia el contenido de las plantillas. Para estas plantillas que a menudo es necesario cambiar, es muy inconveniente si se escriben en el programa. Por lo tanto, se utiliza MySql para almacenar las plantillas y agregar algunos campos adicionales. requerido por el negocio.
Para el servidor, la plantilla de la base de datos se almacenará en caché cuando se inicie. Si es necesario actualizar la plantilla, existen comandos correspondientes para actualizar la caché de la plantilla del servidor en tiempo real, por lo que no hay necesidad de preocuparse por la necesidad de obtenerla. la plantilla de la base de datos cada vez que se envía la plantilla, lo que genera problemas de degradación del rendimiento.
Estructura de la tabla:
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 ` )
)
Descripción del campo:
Campo | ilustrar |
---|---|
tmpl_key | Clave de plantilla (como parámetro para enviar la solicitud de comando de plantilla Mega) |
título | Título de la plantilla |
plantilla | Contenido de la plantilla, el formato de almacenamiento es json. |
creado_en | tiempo de creación |
actualizado_en | Hora de actualización |
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模板命令请求的参数定义
Los archivos de configuración se colocan uniformemente en el directorio de configuración y cada servidor tiene una configuración independiente.
[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
Inicie el servidor de acuerdo con el archivo de configuración, utilizando cada archivo .ini como nombre de servicio y configuración, como el archivo de configuración config/wechat.ini:
cd Mega-Wechat
//php mega ${配置文件名} ${cmd}
php mega wechat start //开启服务
php mega wechat stop //关闭服务
php mega wechat restart //重启服务
Mega-Wechat utiliza TCP para la comunicación y el protocolo adopta un diseño de protocolo de encabezado fijo + cuerpo del paquete. El formato del protocolo general es el siguiente:
{packLength}{headerLength}{command} {params}{opaque}{bodyLength}{body}
Nota: los espacios entre {command} {params}, cada parámetro de params está separado por espacios.
Protocolo de comando de envío de mensaje de plantilla, cada comando representa el envío de un mensaje de plantilla de WeChat. El cliente envía un comando Enviar al servidor, que ejecutará la API de mensajes de plantilla de WeChat una vez y luego responderá al cliente con el resultado y devolverá una confirmación ACK.
La clase correspondiente es: 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 )
Protocolo de comando de puesta en cola de mensajes de plantilla. Después de recibir el comando, el servidor se unirá inmediatamente a la cola y responderá con una confirmación ACK. Posteriormente, ejecutará el procesamiento de mensajes de la plantilla WeChat después de poner en cola de acuerdo con la cola.
La clase correspondiente es: NetworkPushCommand
/**
* @param $opaque int 发送序号
* @param $openid string 微信openid
* @param $key string 模板key
* @param $data array 自定义变量,可选
*/
new PushCommand ( $ opaque , $ openid , $ key , $ data )
Establezca el protocolo de comando de almacenamiento en caché de plantilla. Después de recibir este comando, el servidor obtendrá el contenido de la plantilla de la base de datos de acuerdo con la clave y lo almacenará en la memoria caché. Si la clave no existe o excede el tamaño de la caché, responderá con mensajes de error relevantes.
La clase correspondiente es: NetworkSetTableCommand
/**
* @param $opaque int 发送序号
* @param $key string 模板key
* @param $fd int 客户端标志,客户端发送命令时可为null
*/
new SetTableCommand ( $ opaque , $ key , $ fd )
Protocolo de comando de respuesta general, devuelve el resultado de la solicitud. Este protocolo se puede utilizar como confirmación ACK y como respuesta a la última solicitud basada en el valor opaco devuelto. El código devuelto se utiliza como código de respuesta y utiliza la misma semántica que el código de estado de respuesta del protocolo HTTP. Si la respuesta es un error, normalmente se incluirá el campo de mensaje. Por ejemplo, si el comando Enviar no se envía, el código de respuesta será 400 y el mensaje será el json devuelto por la interfaz de mensajes de plantilla de WeChat como respuesta.
La clase correspondiente es: NetworkBooleanCommand
/**
* @param $code int 应答状态码
* @param $message string 消息内容
* @param $opaque int 应答序号
*/
new BooleanCommand ( $ code , $ message , $ opaque )
El primero es utilizar el protocolo de envío y el otro es el protocolo Push, los cuales pueden hacer frente a diferentes escenarios.
El protocolo Push se utiliza principalmente para implementaciones que no quieren esperar a que WeChat llame a la API. Específicamente, Push colocará cada mensaje de plantilla en la cola y el servidor responderá de inmediato. En este momento, el cliente puede continuar ejecutando la lógica empresarial sin preocuparse por si el mensaje de plantilla tiene éxito. (El lado del servidor puede garantizar el consumo de este mensaje)
El protocolo de envío también envía mensajes de plantilla. A diferencia de Push, el servidor responderá con el resultado después de llamar a la API de mensajes de plantilla de WeChat. Después de recibir la respuesta, el cliente puede obtener el resultado enviado (la respuesta es el protocolo de resultado, el código devuelto es 200 si tiene éxito y el código 400 si falla, y el mensaje es el json del resultado devuelto por WeChat) En función del resultado, el cliente puede realizar el procesamiento lógico correspondiente.
Hay varios problemas con el protocolo de envío:
En comparación con los problemas anteriores, la ventaja de este protocolo es que puede conocer el resultado del envío y puede controlar la lógica empresarial para continuar enviando el siguiente mensaje.
Escenario real: si necesita enviar mensajes de plantilla en lotes a un grupo específico de usuarios o a todos los usuarios, puede utilizar este protocolo para lograrlo. Enviar un lote de mensajes de plantilla a los usuarios puede considerarse como una tarea. La tarea contiene datos como la cantidad de mensajes enviados, la cantidad de éxitos, la cantidad de fallas, la clave de la plantilla, etc. La lógica empresarial de envío, recepción y registro del proceso de envío se implementa a través del cliente. Cada respuesta del servidor se utiliza como base para el éxito o el fracaso de la actualización. El proceso de negocio específico es el siguiente:
Se recomienda utilizar el cliente asincrónico Swoole para implementar la lógica empresarial anterior y, después de ejecutarlo, el cliente se puede ejecutar en segundo plano como un proceso demonio y se puede cerrar con kill cuando sea necesario.
Adjunto se muestra una representación de la implementación del cliente:
Finalmente, se adjunta el github DEMO del cliente de código abierto: https://github.com/imRainChen/Mega-WeChat-Client
Si tiene alguna sugerencia, no dude en contactarnos y también puede publicar preguntas y comentarios.
Correo electrónico: [email protected]
Licencia Apache versión 2.0, consulte http://www.apache.org/licenses/LICENSE-2.0.html