群友清幽傲竹总结了关于kbmMW消息的学习总结,感谢清幽同学无私的奉献,如果以下资料对你用帮助,请在心里默念三次,感谢清幽!
1、不同网段间的消息传递需用到网关(gateway)
2、Hub、Spoke是一组
2.1、两端的订阅文本写上 > 即可运行
2.2、接收指定消息的订阅设置法:
服务端的订阅文本:
> //接收所有消息
hello.> //接收来自客户端hello.打头的消息(如客户端消息"hello.你好")
客户端的订阅文本:
> //接收所有消息
MSG.> //接收来自服务端MSG.打头的消息(如服务端消息"MSG.test.哈哈")
2.3、服务端与客户端可订阅多个,多个订阅用回车分隔,如
MSG.>
HELLO.>
2.4、订阅内容是区分大不写的
2.5、客户端发送消息的方法:
procedure TForm1.Button2Click(Sender: TObject);
var
ci:TkbmMWClientIdentity;
msg: string;
begin
ci:=TkbmMWClientIdentity.Create;
try
ci.Username:='someusername';
ci.Password:='somepassword';
ci.ClientLocation:='In the office';
msg := 'MSG.abc.hello';//服务端的订阅如果写"MSG.>"或"MSG.abc.>"或">",就会显示此客户端发来的消息
kbmMWTCPIPIndyMessagingClientTransport1.SendMessage(msg,'',ci,nil,[]);
finally
ci.Free;
end;
end;
2.6、摘自订阅邮件的一段:
For the hub to know what spokes to send to, the spokes needs to tell the hub
what subjects the spoke is subscribing for.
For that purpose, the spoke 'announces' its subscriptions to the hub.
But for the hub to accept any messages about subscriptions, the hub must
subscribe to SUB.> and optionally USB.>
Subscribing only for MSG.> the hub will not get information from the spokes
what subscriptions they accept.
Thus the hub should as minimum subscribe for SUB.> and MSG.> to receceive messages
starting with MSG. from a spoke.
That you see the spoke getting its own message back is actually quite as it should be.
Reason is that the hubs AutoRelay is true, that means that all incoming messages
will be relayed to all spokes
subscribing for messages of that kind. The spoke sending the message also
subscribes for messages of same kind.
How to eliminate that?
Make sure to send the NodeID as part of the subject. Eg.
MSG.SpokesNodeID.somesubject
Then on each spoke have the following subscription list:
!MSG.SpokeNodeID.>
MSG.>
Then the spoke wont receive messages originating from it self.
2.7、如果服务端的订阅不是写">",那么取spoke列表时,客户端的NodeID无法取到(spoke.PeerNodeID),
碰到这个情况,可以在订阅列表里加入"SUB.>"与"USB.>"即可解决。
Hub、PrioritizingSpoke是一组(两端的订阅文本写上 > 即可运行)
2.8、服务端接收消息中打印客户端的参数
procedure TForm1.kbmMWTCPIPIndyMessagingServerTransport1Message(
Sender: TObject;
const TransportStream: IkbmMWCustomMessageTransportStream;
const Args: TkbmMWArrayVariant; UserStream: TkbmMWMemoryStream);
var
ip: string;
transportInfo: TkbmMWTCPIPIndyMessagingServerTransportInfo;
spoke: TkbmMWCustomMessagingSpoke;
conn: TidTCPConnection;
begin
Memo1.Lines.Add('MessageID:'+ TransportStream.MessageID +';Message received:'+TransportStream.SubjectHeader.Subject);
transportInfo := TkbmMWTCPIPIndyMessagingServerTransportInfo(TransportStream.Info.GetObject);
Memo1.Lines.add( Format('transportInfo.ClientTag(对应线程[AThread:TIdPeerThread]ID):%d',[transportInfo.ClientTag]) );
memo1.Lines.Add( Format('peerIp:%s;peerPort:%d;NodeId:%s;ClusterID:%s',[ transportInfo.IP,transportInfo.Port,transportInfo.NodeID,transportInfo.ClusterID]) );
end;
2.9、取Spoke列表
procedure TForm1.Button3Click(Sender: TObject);
var
lst: TList;
spoke:TkbmMWCustomMessagingSpoke;
i: Integer;
strList:TStringList;
ip: string;
begin
try
lst := kbmMWTCPIPIndyMessagingServerTransport1.Hub.Lock;
strlist := TStringList.Create;
for i := 0 to lst.Count-1 do
begin
spoke := TkbmMWCustomMessagingSpoke(lst.Items[i]);
with TkbmMWTCPIPIndyMessagingServerTransportInfo(spoke.info.GetObject) do
begin
myMemo.Lines.Add(Format('PeerIP:%s ; PeerPort:%d',[Conn.Socket.Binding.PeerIP,Conn.Socket.Binding.PeerPort]));
end;
spoke.PeerSubscriptions.AssignToStrings(strList);
myMemo.Lines.Add(Format('PeerNodeID:%s',[spoke.PeerNodeID]));
myMemo.Lines.Add(Format('订阅列表:%s',[strList.Text]));
myMemo.Lines.Add('=========');
end;
finally
kbmMWTCPIPIndyMessagingServerTransport1.Hub.Unlock;
strlist.Free;
end;
end;