redis实现发布(订阅)消息
redis实现发布(订阅)消息
什么是redis的发布订阅(pub/sub)? Pub/Sub功能(means Publish, Subscribe)即发布及订阅功能。基于事件的系统中,Pub/Sub是目前广泛使用的通信模型,它采用事件作为基本的通信机制,提供大规模系统所要求的松散耦合的交互模式:订阅者(如客户端)以事件订阅的方式表达出它有兴趣接收的一个事件或一类事件;发布者(如服务器)可将订阅者感兴趣的事件随时通知相关订阅者。熟悉设计模式的朋友应该了解这与23种设计模式中的观察者模式极为相似。
看到发布订阅的特性,用来做一个简单的实时聊天系统再适合不过了。这是其中之一,当然这样的东西,我们开发中很少涉及到。再举一个常用的,在我们的分布式架构中,常常会遇到读写分离的场景,在写入的过程中,就可以使用redis发布订阅,使得写入值及时发布到各个读的程序中,就保证数据的完整一致性。再比如,在一个博客网站中,有100个粉丝订阅了你,当你发布新文章,就可以推送消息给粉丝们拉。总之场景很多,需要去挖掘。。
Redis的pub/sub是一种消息通信模式,主要的目的是解除消息发布者和消息订阅者之间的耦合, Redis作为一个pub/sub的server, 在订阅者和发布者之间起到了消息路由的功能。
Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。
Redis 客户端可以订阅任意数量的频道。
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的所有客户端。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | // *************************************************************************** } // // Delphi REDIS Client // // Copyright (c) 2015-2017 Daniele Teti // // https://github.com/danieleteti/delphiredisclient // // *************************************************************************** // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // // *************************************************************************** unit MainForm; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, redis.client, redis.commons, redis.netlib.indy, System.threading, Vcl.StdCtrls; type TForm2 = class (TForm) Memo1: TMemo; Edit2: TEdit; Label1: TLabel; Button1: TButton; procedure FormCreate(Sender: TObject); procedure Edit2KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure Button1Click(Sender: TObject); private _redis: IRedisClient; FTask: ITask; FClosing: Boolean; procedure SendChatMessage; procedure OnMessage( const ANickName, AMessage: string ); { Private declarations } public { Public declarations } end; var Form2: TForm2; implementation uses System.json, ShellAPI; {$R *.dfm} procedure TForm2.Button1Click(Sender: TObject); begin ShellExecute(0, pchar( 'open' ), pchar(Application.ExeName), nil, nil, SW_SHOW); end; procedure TForm2.Edit2KeyUp(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_RETURN then begin SendChatMessage; Key := 0; Edit2.Clear; end; end; procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction); begin FClosing := True; end; procedure TForm2.FormCreate(Sender: TObject); begin FClosing := False; Label1.Caption := InputBox( 'Chat user name' , 'What is your user name in this chat?' , 'd.teti' + (100 + Random(999)) .ToString); _redis := NewRedisClient(); FTask := TTask.Run( procedure var r: IRedisClient; begin r := NewRedisClient; r.SUBSCRIBE([ 'chat' ], procedure(channel, message: string ) var jobj: TJSONObject; msg, nickname: string ; begin jobj := TJSONObject.ParseJSONValue(message) as TJSONObject; nickname := jobj.GetValue<TJSONString>( 'nickname' ).Value; msg := jobj.GetValue<TJSONString>( 'message' ).Value; TThread.Synchronize(nil, procedure begin Self.OnMessage(nickname, msg); end); end, function: Boolean begin Result := Assigned(Self) and (not FClosing); end); end); end; procedure TForm2.OnMessage( const ANickName, AMessage: string ); begin Memo1.Lines.Add( '[' + ANickName + '] ' + DateTimeToStr(now)); Memo1.Lines.Add(AMessage); Memo1.Lines.Add( '---' ); end; procedure TForm2.SendChatMessage; var jobj: TJSONObject; begin jobj := TJSONObject.Create; try jobj.AddPair( 'nickname' , Label1.Caption).AddPair( 'message' , Edit2.Text); _redis.PUBLISH( 'chat' , jobj.ToString); finally jobj.Free; end; end; end. |
本文来自博客园,作者:{咏南中间件},转载请注明原文链接:https://www.cnblogs.com/hnxxcxg/p/10481283.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2014-03-06 关于sqlite数据库
2013-03-06 delphi 新老版本数据类型所占内存大小