聊天项目(10) 多服务验证码派发功能

VerifyServer增加redis

我们为了让验证码有一个过期时间,可以利用redis实现,在Verify文件夹用npm安装redis服务。

  1. npm install ioredis

完善config.json

  1. {
  2. "email": {
  3. "user": "secondtonone1@163.com",
  4. "pass": "CRWTAZOSNCWDDQQTllfc"
  5. },
  6. "mysql": {
  7. "host": "81.68.86.146",
  8. "port": 3308,
  9. "passwd": "123456"
  10. },
  11. "redis":{
  12. "host": "81.68.86.146",
  13. "port": 6380,
  14. "passwd": "123456"
  15. }
  16. }

服务里添加redis模块,封装redis操作在redis.js中

  1. const config_module = require('./config')
  2. const Redis = require("ioredis");
  3. // 创建Redis客户端实例
  4. const RedisCli = new Redis({
  5. host: config_module.redis_host, // Redis服务器主机名
  6. port: config_module.redis_port, // Redis服务器端口号
  7. password: config_module.redis_passwd, // Redis密码
  8. });
  9. /**
  10. * 监听错误信息
  11. */
  12. RedisCli.on("error", function (err) {
  13. console.log("RedisCli connect error");
  14. RedisCli.quit();
  15. });
  16. /**
  17. * 根据key获取value
  18. * @param {*} key
  19. * @returns
  20. */
  21. async function GetRedis(key) {
  22. try{
  23. const result = await RedisCli.get(key)
  24. if(result === null){
  25. console.log('result:','<'+result+'>', 'This key cannot be find...')
  26. return null
  27. }
  28. console.log('Result:','<'+result+'>','Get key success!...');
  29. return result
  30. }catch(error){
  31. console.log('GetRedis error is', error);
  32. return null
  33. }
  34. }
  35. /**
  36. * 根据key查询redis中是否存在key
  37. * @param {*} key
  38. * @returns
  39. */
  40. async function QueryRedis(key) {
  41. try{
  42. const result = await RedisCli.exists(key)
  43. // 判断该值是否为空 如果为空返回null
  44. if (result === 0) {
  45. console.log('result:<','<'+result+'>','This key is null...');
  46. return null
  47. }
  48. console.log('Result:','<'+result+'>','With this value!...');
  49. return result
  50. }catch(error){
  51. console.log('QueryRedis error is', error);
  52. return null
  53. }
  54. }
  55. /**
  56. * 设置key和value,并过期时间
  57. * @param {*} key
  58. * @param {*} value
  59. * @param {*} exptime
  60. * @returns
  61. */
  62. async function SetRedisExpire(key,value, exptime){
  63. try{
  64. // 设置键和值
  65. await RedisCli.set(key,value)
  66. // 设置过期时间(以秒为单位)
  67. await RedisCli.expire(key, exptime);
  68. return true;
  69. }catch(error){
  70. console.log('SetRedisExpire error is', error);
  71. return false;
  72. }
  73. }
  74. /**
  75. * 退出函数
  76. */
  77. function Quit(){
  78. RedisCli.quit();
  79. }
  80. module.exports = {GetRedis, QueryRedis, Quit, SetRedisExpire,}

server.js中包含redis.js

  1. const redis_module = require('./redis')

获取验证码之前可以先查询redis,如果没查到就生成uid并且写入redis

  1. async function GetVarifyCode(call, callback) {
  2. console.log("email is ", call.request.email)
  3. try{
  4. let query_res = await redis_module.GetRedis(const_module.code_prefix+call.request.email);
  5. console.log("query_res is ", query_res)
  6. if(query_res == null){
  7. }
  8. let uniqueId = query_res;
  9. if(query_res ==null){
  10. uniqueId = uuidv4();
  11. if (uniqueId.length > 4) {
  12. uniqueId = uniqueId.substring(0, 4);
  13. }
  14. let bres = await redis_module.SetRedisExpire(const_module.code_prefix+call.request.email, uniqueId,600)
  15. if(!bres){
  16. callback(null, { email: call.request.email,
  17. error:const_module.Errors.RedisErr
  18. });
  19. return;
  20. }
  21. }
  22. console.log("uniqueId is ", uniqueId)
  23. let text_str = '您的验证码为'+ uniqueId +'请三分钟内完成注册'
  24. //发送邮件
  25. let mailOptions = {
  26. from: 'secondtonone1@163.com',
  27. to: call.request.email,
  28. subject: '验证码',
  29. text: text_str,
  30. };
  31. let send_res = await emailModule.SendMail(mailOptions);
  32. console.log("send res is ", send_res)
  33. callback(null, { email: call.request.email,
  34. error:const_module.Errors.Success
  35. });
  36. }catch(error){
  37. console.log("catch error is ", error)
  38. callback(null, { email: call.request.email,
  39. error:const_module.Errors.Exception
  40. });
  41. }
  42. }

验证服务联调

开启VerifyServer和GateServer,再启动客户端,点击获取验证码,客户端就会发送请求给GateServer,GateServer再调用内部服务VerifyServer。最后将请求返回客户端,完成了验证码发送的流程。

如果10分钟之内多次请求,因为验证码被缓存在redis中,所以会被复用返回给客户端。

https://cdn.llfc.club/1711079058273.jpg

看起来客户端收到服务器的回复了,我们去邮箱看看是否收到验证码

https://cdn.llfc.club/1711080431619.jpg

确实收到了验证码。好的多服务调用实现了,大家可以把这个功能理解下,接下来去实现注册逻辑。

热门评论

热门文章

  1. 解密定时器的实现细节

    喜欢(566) 浏览(1884)
  2. C++ 类的继承封装和多态

    喜欢(588) 浏览(2610)
  3. slice介绍和使用

    喜欢(521) 浏览(1742)
  4. Linux环境搭建和编码

    喜欢(594) 浏览(5594)
  5. windows环境搭建和vscode配置

    喜欢(587) 浏览(1717)

最新评论

  1. 线程安全的无锁栈 secondtonone1:谢谢支持,如果pop的次数大于push的次数是会让线程处于重试的,这个是测试用例,必须满足push和pop的次数相同,实际情况不会这么使用。栈的设计没有问题。
  2. 再谈单例模式 secondtonone1:是的,C++11以后返回局部static变量对象能保证线程安全了。
  3. Linux环境搭建和编码 恋恋风辰:Linux环境下go的安装比较简单,可以不用设置GOPATH环境变量,后期我们学习go mod 之后就拜托了go文件目录的限制了。
  4. C++ 类的拷贝构造、赋值运算、单例模式 secondtonone1:好的,已修复。
  5. 双链表实现LRU算法 secondtonone1:双链表插入和删除节点是本篇的难点,多多练习即可。

个人公众号

个人微信