Closed SheppeR closed 8 years ago
Are you talking about HTTP or some other protocol?
Hi, I am using ChannelTcpClient and ChannelTcpListener on WPF and Console project. My server need to send some serialized 'Packets' on all clients connected without a request.
example: Client1 -> connect -> Server Server -> send to -> Client1 FriendsList 'Packet' Client2 -> connect -> Server Server -> send to -> Client2 FriendsList 'Packet'
i am looking for something like OnReceiveMessage event on client side
client = new ChannelTcpClient(
new MicroMessageEncoder(new JsonMessageSerializer()),
new MicroMessageDecoder(new JsonMessageSerializer()));
client.MessageReceived += OnMessageReceived;
Something like this?
class Program
{
static List<ITcpChannel> _clients = new List<ITcpChannel>();
static void Main(string[] args)
{
var listener = new ChannelTcpListener();
listener.ClientConnected += OnConnected;
listener.ClientDisconnected += OnDisconnect;
}
private static void OnDisconnect(object sender, ClientDisconnectedEventArgs e)
{
lock (_clients)
{
foreach (var client in _clients)
{
client.Send("Your message");
}
_clients.Remove(e.Channel);
}
}
private static void OnConnected(object sender, ClientConnectedEventArgs e)
{
lock (_clients)
_clients.Add(e.Channel);
}
}
Not exactly, I am sorry if my request is not clear. I am using something similar on my server side, but i am looking for an event on the client side for handle message without a client.Send.
Currently on the client, i can only receive message if i request it but i need to receive a lot of different type of serialized message without the request for each
Like this:
client.MessageReceived += OnMessageReceived;
private void OnMessageReceived(ITcpChannel channel, object message)
{
var mType = message.GetType();
if (mType == typeof(Login_Response))
{
//TODO
}
else if (mType == typeof(Login_Status))
{
//TODO
}
}
The client is 100% asynchronous. The request/reply pattern is just a layer on top. Unfortunately there is no straightforward way currently to push messages.
However, it is possible by using the Filterhandler.
var client = new ChannelTcpClient(
new MicroMessageEncoder(new DataContractMessageSerializer()),
new MicroMessageDecoder(new DataContractMessageSerializer()));
// this delegate is invoked each time a new message arrives,
// no matter if it's pushed or a reply.
client.Filter = (channel, message) =>
{
Console.WriteLine("Got a message from the server.");
return ClientFilterResult.Accept;
};
If that doesn't work for you, it's quite easy to build a client from the TcpChannel
directly.
public class MyClient : TcpChannel
{
public MyClient(IBufferSlice readBuffer, IMessageEncoder encoder, IMessageDecoder decoder) : base(readBuffer, encoder, decoder)
{
}
public MyClient()
: base(
new BufferSlice(new byte[65535], 0, 65535),
new MicroMessageEncoder(new DataContractMessageSerializer()),
new MicroMessageDecoder(new DataContractMessageSerializer()))
{
}
/// <summary>
/// Add client connect functionality
/// </summary>
public void Connect(string remoteAddress, int port)
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(remoteAddress, port);
//assign the socket to the base class
Assign(socket);
}
}
Which can be invoked like.
var myClient = new MyClient();
myClient.MessageReceived = (channel, message) =>
{
//this is invoked on each message that is pushed from the server
};
myClient.Connect("SomeServer", 7374);
This work like a charm
client.Filter = (channel, message) =>
{
Console.WriteLine("Got a message from the server.");
return ClientFilterResult.Accept;
};
Thanks for the support and your time on this issue.
Hi, i am just starting to use Griffin.Framework, and i am looking for handle message without sending request on client side
Ex: (CLIENT) request_friendslist (SERVER) reply_friend1 (SERVER) reply_friend2 (SERVER) reply_friend3
Sorry for my bad english. Best regards SheppeR