Mega-Wechat est un service d'envoi de modèles de messages WeChat, mis en œuvre sur la base du framework réseau Swoole. Il prend en charge l'envoi d'un grand nombre de messages et exécute simultanément l'interface de message du modèle d'envoi. L'ensemble du processus d'envoi est exécuté selon la file d'attente sur la base du premier arrivé, premier servi. Prend en charge les modèles de messages personnalisés, qui peuvent être modifiés et utilisés à tout moment.
Lorsque nous opérons dans une entreprise, nous devons fréquemment envoyer des modèles de messages WeChat à des utilisateurs désignés. À ce moment-là, la mise en œuvre d'autres entreprises est plus urgente, nous codons donc simplement en dur certains modèles de messages dans le contrôleur et exécutons les commandes pour terminer le processus. exigences de fonctionnement lors de leur utilisation. Par conséquent, lors de la modification du contenu du modèle, vous devez modifier le code et le mettre à jour avec git. De plus, en raison du problème du processus unique, l'envoi d'un grand nombre de messages de modèle prendra beaucoup de temps (principalement en raison du temps nécessaire). prend beaucoup de temps à curl pour appeler l'interface WeChat).
Plusieurs solutions me sont venues à l’esprit pour cela :
La première méthode implémente directement un client multi-processus pour appeler WeChat pour envoyer l'API de messages modèles via curl. Cette méthode est simple et rapide à mettre en œuvre, mais elle ne peut pas prendre en charge les besoins d'autres entreprises pour appeler des messages modèles.
La deuxième méthode consiste à demander à un processus de distribuer les tâches et de créer plusieurs sous-processus, et d'interroger en permanence la file d'attente Redis à travers les sous-processus. Cette solution est également relativement simple à mettre en œuvre, mais la contrôlabilité est si mauvaise qu'elle est fondamentalement difficile à mettre en œuvre. contrôle.
La troisième solution, actuellement utilisée, consiste à utiliser swoole pour implémenter un service similaire à une file d'attente de messages. Plusieurs tâches effectuent des opérations de curl lentes pour ajuster l'API WeChat, et les résultats de l'exécution peuvent être renvoyés au client. Étant donné que swoole est un cadre réseau très puissant et peut recevoir beaucoup de concurrence, en théorie, swoole peut gérer un grand nombre de demandes d'envoi de modèles de messages. Cependant, comme l'API d'envoi de modèles de messages de WeChat prend relativement du temps, un grand nombre de demandes sont nécessaires. demander la livraison Exécuter dans la tâche car La vitesse de traitement n'est pas aussi rapide que la vitesse de réception, ce qui entraînera un débordement de tampon. Par conséquent, Mega-Wechat utilise une file d'attente de fichiers pour mettre d'abord toutes les demandes dans la file d'attente. Lorsque le processus de tâche est inactif, les demandes sont retirées de la file d'attente. la file d'attente et livré. Accédez à la tâche pour traiter la demande d'envoi du modèle de message. Une telle implémentation ne provoquera pas de débordements de tampon et peut prendre en charge une grande quantité de concurrence. Cependant, étant donné que WeChat dispose d’un ensemble de règles et de restrictions sur les modèles de messages, un grand nombre d’appels API ne sont que théoriques.
L'architecture du système Mega-Wechat est présentée dans la figure ci-dessous :
Description du processus d'exécution du système :
La description ci-dessus est un processus synchrone, qui peut être un traitement asynchrone ou synchrone pour le client.
config/ 服务器配置
libs/
Network/
Server/
Swoole/ Mega核心类库
Wechat/ 微信API
logs/
vendor/ 支持composer,依赖monolog写日志
autoload.php
mega Mega命令入口
premier pas Pour installer PHP, la version 5.6 ou supérieure est requise. Parce que la file d'attente côté serveur utilise la fonction SPL et la syntaxe des nouvelles fonctionnalités de PHP
Étape 2 Installez Mysql, n'importe quelle version convient.
miam, installe mysql
Après une installation réussie, Mysql doit créer une table mega_wechat_template. La structure détaillée est présentée dans le chapitre suivant.
Étape 3 Avant d'installer l'extension swoole, vous devez vous assurer que le logiciel suivant a été installé sur le système
php-5.3.10 ou supérieur gcc-4.4 ou supérieur make autoconf
Adresse de téléchargement
https://github.com/swoole/swoole-src/releases
http://pecl.php.net/package/swoole
http://git.oschina.net/matyhtf/swoole
Après avoir téléchargé le package de code source, entrez le répertoire du code source dans le terminal et exécutez les commandes suivantes pour compiler et installer
CD Swoole
phpize ./configurer
faire
faire installer
Les modèles WeChat sont stockés sur le serveur Mega-Wechat. En effet, la plupart des entreprises doivent fréquemment modifier le contenu des modèles. Pour ces modèles qui doivent souvent être modifiés, il est très gênant s'ils sont écrits dans le programme. Par conséquent, MySql est utilisé pour stocker les modèles et ajouter des champs supplémentaires. requis par l’entreprise.
Pour le serveur, le modèle de base de données sera mis en cache au démarrage. Si le modèle doit être mis à jour, il existe des commandes correspondantes pour mettre à jour le cache de modèles du serveur en temps réel. Il n'y a donc pas lieu de s'inquiéter de la nécessité de l'obtenir. le modèle de la base de données à chaque fois que le modèle est envoyé, ce qui entraîne une question de dégradation des performances.
Structure du tableau :
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 ` )
)
Description du champ :
Champ | illustrer |
---|---|
clé_tmpl | Clé de modèle (en tant que paramètre pour l'envoi d'une demande de commande de modèle Mega) |
titre | Titre du modèle |
modèle | Contenu du modèle, le format de stockage est json |
créé_à | temps de création |
mise à jour_at | Heure de mise à jour |
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模板命令请求的参数定义
Les fichiers de configuration sont uniformément placés dans le répertoire de configuration et chaque serveur a une configuration indépendante.
[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
Démarrez le serveur selon le fichier de configuration, en utilisant chaque fichier .ini comme nom de service et configuration, comme le fichier de configuration config/wechat.ini :
cd Mega-Wechat
//php mega ${配置文件名} ${cmd}
php mega wechat start //开启服务
php mega wechat stop //关闭服务
php mega wechat restart //重启服务
Mega-Wechat utilise TCP pour la communication et le protocole adopte une conception de protocole en-tête fixe + corps de paquet. Le format général du protocole est le suivant :
{packLength}{headerLength}{command} {params}{opaque}{bodyLength}{body}
Remarque : les espaces entre {command} {params}, chaque paramètre params est séparé par des espaces.
Protocole de commande d'envoi de message de modèle, chaque commande représente un envoi de message de modèle WeChat. Le client envoie une commande Send au serveur, qui exécutera une fois l'API de message du modèle WeChat, puis répondra au client avec le résultat et renverra une confirmation ACK.
La classe correspondante est : 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 )
Modèle de protocole de commande de mise en file d'attente des messages. Après avoir reçu la commande, le serveur rejoindra immédiatement la file d'attente et répondra avec une confirmation ACK. Par la suite, il exécutera le traitement du message du modèle WeChat après la mise en file d'attente en fonction de la file d'attente.
La classe correspondante est : NetworkPushCommand
/**
* @param $opaque int 发送序号
* @param $openid string 微信openid
* @param $key string 模板key
* @param $data array 自定义变量,可选
*/
new PushCommand ( $ opaque , $ openid , $ key , $ data )
Définir le protocole de commande de mise en cache du modèle. Après avoir reçu cette commande, le serveur obtiendra le contenu du modèle de la base de données en fonction de la clé et le mettra en cache dans la mémoire. Si la clé n'existe pas ou dépasse la taille du cache, il répondra avec des messages d'erreur pertinents.
La classe correspondante est : NetworkSetTableCommand
/**
* @param $opaque int 发送序号
* @param $key string 模板key
* @param $fd int 客户端标志,客户端发送命令时可为null
*/
new SetTableCommand ( $ opaque , $ key , $ fd )
Protocole de commande de réponse générale, renvoie le résultat de la demande. Ce protocole peut être utilisé comme confirmation ACK et comme réponse à la dernière requête basée sur la valeur opaque renvoyée. Le code renvoyé est utilisé comme code de réponse, en utilisant la même sémantique que le code d'état de réponse du protocole HTTP. Si la réponse est une erreur, le champ de message sera généralement inclus. Par exemple, si la commande Envoyer ne parvient pas à être envoyée, le code de réponse sera 400 et le message sera le json renvoyé par l'interface de message du modèle WeChat comme réponse.
La classe correspondante est : NetworkBooleanCommand
/**
* @param $code int 应答状态码
* @param $message string 消息内容
* @param $opaque int 应答序号
*/
new BooleanCommand ( $ code , $ message , $ opaque )
La première consiste à utiliser le protocole Send et l’autre le protocole Push, qui peuvent tous deux faire face à différents scénarios.
Le protocole Push est principalement utilisé pour les implémentations qui ne souhaitent pas attendre que WeChat appelle l'API. Plus précisément, Push mettra chaque modèle de message dans la file d'attente et le serveur répondra immédiatement. À ce stade, le client peut continuer à exécuter la logique métier sans se soucier de la réussite du modèle de message. (Le côté serveur peut garantir la consommation de ce message)
Le protocole Send envoie également des modèles de messages. Contrairement à Push, le serveur répondra avec le résultat après avoir appelé l'API de message modèle WeChat. Après avoir reçu la réponse, le client peut obtenir le résultat envoyé (la réponse est le protocole Result, le code renvoyé est 200 en cas de succès, et le code 400 est renvoyé en cas d'échec, et le message est le json du résultat renvoyé par WeChat) . Sur la base du résultat, le client peut effectuer le traitement logique correspondant.
Il existe plusieurs problèmes avec le protocole Send :
Par rapport aux problèmes ci-dessus, l'avantage de ce protocole est qu'il peut connaître le résultat de l'envoi et contrôler la logique métier pour savoir s'il faut continuer à envoyer le message suivant.
Scénario réel : si vous devez envoyer des modèles de messages par lots à un groupe spécifié d'utilisateurs ou à tous les utilisateurs, vous pouvez utiliser ce protocole pour y parvenir. L'envoi d'un lot de messages modèles aux utilisateurs peut être considéré comme une tâche. La tâche contient des données telles que le nombre de messages envoyés, le nombre de réussites, le nombre d'échecs, la clé du modèle, etc. La logique métier d'envoi, de réception et d'enregistrement du processus d'envoi est mise en œuvre via le client. Chaque réponse du serveur est utilisée comme base du succès ou de l'échec de la mise à jour. Le processus métier spécifique est le suivant :
Il est recommandé d'utiliser le client asynchrone Swoole pour implémenter la logique métier ci-dessus, et après son exécution, le client peut être exécuté en arrière-plan en tant que processus démon et peut être fermé avec kill si nécessaire.
Vous trouverez ci-joint un rendu d'implémentation client :
Enfin, le client open source DEMO github est joint : https://github.com/imRainChen/Mega-WeChat-Client
Si vous avez des suggestions, n'hésitez pas à nous contacter et vous pouvez également poster des questions et des commentaires.
Courriel : [email protected]
Licence Apache version 2.0, voir http://www.apache.org/licenses/LICENSE-2.0.html