Mega-Wechat é um serviço de envio de mensagens modelo WeChat, implementado com base na estrutura de rede Swoole. Ele suporta o envio de um grande número de mensagens e executa a interface de mensagem do modelo de envio simultaneamente. Todo o processo de envio é executado de acordo com a fila, por ordem de chegada. Suporta modelos de mensagens personalizadas, que podem ser alteradas e usadas a qualquer momento.
Ao operar em uma empresa, precisamos enviar frequentemente mensagens de modelo do WeChat para usuários designados. Nesse momento, a implementação de outros negócios é mais urgente, então simplesmente codificamos algumas mensagens de modelo no controlador e executamos os comandos para concluir o processo. requisitos de operação ao usá-los. Portanto, ao alterar o conteúdo do modelo, você precisa alterar o código e atualizá-lo com git. Além disso, devido ao problema do processo único, o envio de um grande número de mensagens de modelo consumirá muito tempo (principalmente devido ao tempo). consumindo tempo de curl chamando a interface do WeChat).
Várias soluções vieram à mente para isso:
O primeiro método implementa diretamente um cliente multiprocesso para chamar o WeChat para enviar mensagens de modelo API por meio de curl. Este método é simples e rápido de implementar, mas não pode suportar as necessidades de outras empresas para chamar mensagens de modelo.
O segundo método é fazer com que um processo distribua tarefas e bifurque vários subprocessos e pesquise continuamente a fila de redis através dos subprocessos. Essa solução também é relativamente simples de implementar, mas a controlabilidade é tão baixa que é basicamente difícil de implementar. controlar.
A terceira solução, que está em uso atualmente, é usar o swoole para implementar um serviço semelhante a uma fila de mensagens. Várias tarefas executam operações lentas para ajustar a API do WeChat e os resultados da execução podem ser retornados ao cliente. Como o swoole é uma estrutura de rede muito poderosa e pode receber muita simultaneidade, em teoria, o swoole pode lidar com um grande número de solicitações para enviar mensagens de modelo. No entanto, como a API de envio de mensagens de modelo do WeChat é relativamente demorada, um grande número de. solicitar entrega Executar na tarefa porque A velocidade de processamento não é tão rápida quanto a velocidade de recebimento, o que levará ao estouro do buffer. Portanto, o Mega-Wechat usa uma fila de arquivos para colocar todas as solicitações na fila primeiro. Quando o processo da tarefa está ocioso, as solicitações são retiradas. a fila e entregue. Vá para a tarefa para processar a solicitação para enviar a mensagem modelo. Tal implementação não causará buffer overflows e poderá suportar uma grande quantidade de simultaneidade. No entanto, como o WeChat possui um conjunto de regras e restrições para mensagens de modelo, um grande número de chamadas de API são apenas teóricas.
A arquitetura do sistema Mega-Wechat é mostrada na figura abaixo:
Descrição do processo de execução do sistema:
A descrição acima é um processo síncrono, que pode ser um processamento assíncrono ou síncrono para o cliente.
config/ 服务器配置
libs/
Network/
Server/
Swoole/ Mega核心类库
Wechat/ 微信API
logs/
vendor/ 支持composer,依赖monolog写日志
autoload.php
mega Mega命令入口
primeiro passo Para instalar o PHP, é necessária a versão 5.6 ou superior. Porque a fila do lado do servidor usa a função SPL e a sintaxe dos novos recursos do PHP
Etapa 2 Instale o Mysql, qualquer versão está bem.
yum instale o mysql
Após a instalação bem-sucedida, o Mysql precisa criar uma tabela mega_wechat_template. A estrutura detalhada é apresentada no próximo capítulo.
Etapa 3 Antes de instalar a extensão swoole, você deve garantir que o seguinte software foi instalado no sistema
php-5.3.10 ou superior gcc-4.4 ou superior make autoconf
Endereço de download
https://github.com/swoole/swoole-src/releases
http://pecl.php.net/package/swoole
http://git.oschina.net/matyhtf/swoole
Após baixar o pacote do código-fonte, entre no diretório do código-fonte no terminal e execute os seguintes comandos para compilar e instalar
cd swoole
phpize./configure
fazer
fazer instalar
Os modelos WeChat são armazenados no servidor Mega-Wechat. Isso ocorre porque a maioria das empresas precisa modificar frequentemente o conteúdo dos modelos. Para esses modelos que muitas vezes precisam ser alterados, é muito inconveniente se eles forem gravados no programa. Portanto, o MySql é usado para armazenar os modelos e adicionar alguns campos adicionais. exigido pelo negócio.
Para o servidor, o modelo de banco de dados será armazenado em cache quando for iniciado. Se o modelo precisar ser atualizado, existem comandos correspondentes para atualizar o cache do modelo do servidor, portanto, não há necessidade de se preocupar com a necessidade de obter. o modelo do banco de dados sempre que o modelo é enviado, resultando em problemas de degradação de desempenho.
Estrutura da tabela:
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 ` )
)
Descrição do campo:
Campo | ilustrar |
---|---|
tmpl_key | Chave de modelo (como parâmetro para enviar solicitação de comando de modelo Mega) |
título | Título do modelo |
modelo | Conteúdo do modelo, formato de armazenamento é json |
criado_em | hora de criação |
atualizado_em | Hora de atualização |
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模板命令请求的参数定义
Os arquivos de configuração são colocados uniformemente no diretório de configuração e cada servidor possui uma configuração independente.
[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 o servidor de acordo com o arquivo de configuração, usando cada arquivo .ini como nome de serviço e configuração, como o arquivo de configuração config/wechat.ini:
cd Mega-Wechat
//php mega ${配置文件名} ${cmd}
php mega wechat start //开启服务
php mega wechat stop //关闭服务
php mega wechat restart //重启服务
Mega-Wechat usa TCP para comunicação e o protocolo adota um design de protocolo de cabeçalho fixo + corpo de pacote. O formato geral do protocolo é o seguinte:
{packLength}{headerLength}{command} {params}{opaque}{bodyLength}{body}
Nota: nos espaços entre {command} {params}, cada parâmetro params é separado por espaços.
Protocolo de comando de envio de mensagem de modelo, cada comando representa um envio de mensagem de modelo WeChat. O cliente envia um comando Enviar ao servidor, que executará a API de mensagem do modelo WeChat uma vez e então responderá ao cliente com o resultado e retornará uma confirmação ACK.
A classe correspondente é: 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 enfileiramento de mensagens de modelo. Após receber o comando, o servidor entrará imediatamente na fila e responderá com a confirmação ACK. Posteriormente, executará o processamento da mensagem do modelo WeChat após o enfileiramento de acordo com a fila.
A classe correspondente é: NetworkPushCommand
/**
* @param $opaque int 发送序号
* @param $openid string 微信openid
* @param $key string 模板key
* @param $data array 自定义变量,可选
*/
new PushCommand ( $ opaque , $ openid , $ key , $ data )
Defina o protocolo de comando de cache de modelo. Após receber este comando, o servidor obterá o conteúdo do modelo do banco de dados de acordo com a chave e armazenará em cache na memória. Se a chave não existir ou exceder o tamanho do cache, ele responderá com mensagens de erro relevantes.
A classe correspondente é: NetworkSetTableCommand
/**
* @param $opaque int 发送序号
* @param $key string 模板key
* @param $fd int 客户端标志,客户端发送命令时可为null
*/
new SetTableCommand ( $ opaque , $ key , $ fd )
Protocolo de comando de resposta geral, retorna o resultado da solicitação. Este protocolo pode ser usado como confirmação de ACK e como resposta à última solicitação com base no valor opaco retornado. O código retornado é usado como código de resposta, usando a mesma semântica do código de status de resposta do protocolo HTTP. Se a resposta for um erro, o campo da mensagem geralmente será incluído. Por exemplo, se o comando Enviar não for enviado, o código de resposta será 400 e a mensagem será o json retornado pela interface de mensagem do modelo WeChat como resposta.
A classe correspondente é: NetworkBooleanCommand
/**
* @param $code int 应答状态码
* @param $message string 消息内容
* @param $opaque int 应答序号
*/
new BooleanCommand ( $ code , $ message , $ opaque )
O primeiro é usar o protocolo Send e o outro é o protocolo Push, ambos capazes de lidar com diferentes cenários.
O protocolo Push é usado principalmente para implementações que não desejam esperar que o WeChat chame a API. Especificamente, o Push colocará cada mensagem do modelo na fila e o servidor responderá imediatamente. Nesse momento, o cliente pode continuar a executar a lógica de negócios sem se preocupar se a mensagem do modelo foi bem-sucedida. (O lado do servidor pode garantir o consumo desta mensagem)
O protocolo Send também envia mensagens de modelo. Ao contrário do Push, o servidor responderá com o resultado após chamar a API de mensagem de modelo do WeChat. Após receber a resposta, o cliente pode obter o resultado enviado (a resposta é o protocolo Result, o código retornado é 200 se for bem sucedido, e o código 400 é retornado se falhar, e a mensagem é o json do resultado retornado pelo WeChat) . Com base no resultado, o cliente pode fazer o processamento lógico correspondente.
Existem vários problemas com o protocolo Send:
Em comparação com as questões acima, a vantagem deste protocolo é que ele pode saber o resultado do envio e controlar a lógica de negócios para continuar enviando a próxima mensagem.
Cenário real: se você precisar enviar mensagens modelo em lotes para um grupo específico de usuários ou para todos os usuários, poderá usar este protocolo para fazer isso. O envio de um lote de mensagens de modelo aos usuários pode ser considerado uma tarefa. A tarefa contém dados como o número de mensagens enviadas, o número de sucessos, o número de falhas, a chave do modelo, etc. A lógica de negócio de envio, recebimento e registro do processo de envio é implementada através do cliente. Cada resposta do servidor é usada como base para o sucesso ou fracasso da atualização. O processo de negócios específico é o seguinte:
Recomenda-se usar o cliente assíncrono Swoole para implementar a lógica de negócios acima e, após a execução, o cliente pode ser executado em segundo plano como um processo daemon e pode ser fechado com kill quando necessário.
Em anexo está uma renderização da implementação do cliente:
Finalmente, o github Client DEMO de código aberto está anexado: https://github.com/imRainChen/Mega-WeChat-Client
Se você tiver alguma sugestão, não hesite em nos contatar e também poderá postar perguntas e comentários.
E-mail: [email protected]
Licença Apache versão 2.0, consulte http://www.apache.org/licenses/LICENSE-2.0.html