在Silverlight 一般是采用wcf進行數據通訊,畢竟wcf在數據結構定義上非常方便,但如果你想用Silverlight下的socket進行對象傳偷就不得不封裝處理一下,在Silverlight下有XML序列化也是非常方便的,但這樣會導致消息比較臃腫,同樣還要對數據包分析處理包括粘包等工作.如果你要面對這些問題那以下組件也許會給你帶來很大的幫助.Beetle.SL是封裝Silverlight socket tcp的一個開源組件.
組件封裝方便使用的TcpChannel,通過事件定義就能方便進行tcp連接,數據接收事件定義等.更重要的是組件提供靈活的協議分析器,可以根據分析器直接實現對象和byte[]的轉換.除了提供數據對象轉換外還提供tcp粘包問題,可以讓使用者完全不用關心這些煩鎖的事情.
組件協議分析器的制定也是非常靈活,除了提供基於結束符和頭描述大小的分包機制外,使用者還可以根據自己的需要實現自己的封包協議.自帶的協議分析所組裝的協也是基於基礎類型的存格式.所以服務端也可以方便地使用c++,java等平台實現.
連接定義
mChannel = new TcpChannel(new HeadSizePackage());
mChannel.Connected += OnConnected;
mChannel.Error += OnError;
mChannel.Receive += OnReceive;
mChannel.Connect(txtIPAddress.Text, 4505);
private void OnReceive(object sender, EventChannelReceiveArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
Register reg =(Register)e.Message;
txtLog.Text+= string.Format("Name:{0}\r\n",reg.Name);
txtLog.Text += string.Format("EMail:{0}\r\n", reg.EMail);
});
}
private void OnError(object sender, EventChannelErrorArgs e)
{
this.Dispatcher.BeginInvoke(() =>
{
this.txtStatus.Content = e.Error.Message;
});
}
private void OnConnected(object sender, EventChannelArges e)
{
this.Dispatcher.BeginInvoke(() =>
{
this.txtStatus.Content = "Connected!";
this.cmdRegister.IsEnabled = true;
});
}
定義消息
public class Register:IMessage
{
public string Name;
public string EMail;
public void Save(BufferWriter writer)
{
writer.Write(Name);
writer.Write(EMail);
}
public void Load(BufferReader reader)
{
Name = reader.ReadString();
EMail = reader.ReadString();
}
}
發送消息
Register reg = new Register();
reg.Name = txtName.Text;
reg.EMail = txtEMail.Text;
mChannel.Send(reg);
//以上消息的封裝格式是
int32 //總長度 4byte
int32 //消息類型名稱長度 4byte
string //消息名稱utf8編碼 byte[]
int32 // Name長度4byte
string // Name utf8編碼 byte[]
int32 //EMail 長度4byte
string // EMail utf8編碼byte[]
以上協義格式相信做過socket通訊的朋友都比較熟悉,這樣的協議分析c++,java也是很方便就能處理得到.如果你對這個組件感興趣可以到以下地址獲取完整代碼
