[C # source code] breeze IM V3.1 supports sending images through TCP communication,
Updated source code
The database (the database remains unchanged as before) uses sql2005, which is not convenient for users who can download SQL script files.
Several friends said they hoped that the breeze IM could support image sending. So they learned some related knowledge about image sending and implemented image sending in breeze IMV3.1.
If the P2P channels between clients are connected, the requests are sent directly between clients without passing through the server.
If the P2P channel is not connected, it is forwarded through the server.
:
The following is a brief introduction to related knowledge.
In TCP communication, the Image class itself does not support serialization.
If you want to send the message, you need to make some modifications. Simply put, the Image class is converted into binary data before serialization. After serialization, the binary data is parsed into an Image class.
We use the open-source protobuf.net serializer.
Package IMage classes
Using System; using System. collections. generic; using System. text; using ProtoBuf; using System. drawing; using System. IO; using ProtoBuf; namespace SimpleIM. business {[ProtoContract] public class ImageWrapper {// <summary> // store the Image object as a private byte array // </summary> [ProtoMember (1)] private byte [] _ imageData; // <summary> // image name // </summary> [ProtoMember (2)] public string ImageName {get; set ;} /// <sum Mary >/// Image object /// </summary> public Image {get; set ;} /// <summary> /// private non-parameter constructor used for deserialization // </summary> private ImageWrapper () {}/// <summary> /// create a new ImageWrapper class // </summary> /// <param name = "imageName"> </param>/ // <param name = "image"> </param> public ImageWrapper (string imageName, image image) {this. imageName = imageName; this. image = image;} // <summary> // before serialization, convert the Image Binary data // </summary> [ProtoBeforeSerialization] private void Serialize () {if (Image! = Null) {// We need to decide how to convert our image to its raw binary form here using (MemoryStream inputStream = new MemoryStream ()) {// For basic image types the features are part of. net framework Image. save (inputStream, Image. rawFormat); // If we wanted to include additional data processing here // such as compression, encryption etc we can still use the features provided NetworkComms. net // e.g. see DPSManager. getDataProcessor <LZMACompressor> () // Store the binary image data as bytes [] _ imageData = inputStream. toArray () ;}}/// <summary> /// during deserialization, convert binary data to image objects // </summary> [ProtoAfterDeserialization] private void Deserialize () {MemoryStream MS = new MemoryStream (_ imageData ); // If we added custom data processes we have the perform the reverse operations here before // trying to recreate the image object // e.g. DPSManager. getDataProcessor <LZMACompressor> () Image = Image. fromStream (MS); _ imageData = null ;}}}
Modify the contract class used to transmit chat information to include related images.
Using System; using System. collections. generic; using System. text; using ProtoBuf; using System. IO; using System. runtime. serialization. formatters. binary; using System. componentModel; namespace SimpleIM. business {// <summary> /// this contract class stores chat conversation messages // </summary> [ProtoContract] public class NewChatContract {// user ID [ProtoMember (1)] public string UserID {get; set;} // username [ProtoMember (2)] public string UserNam E {get; set ;}// target user ID [ProtoMember (3)] public string DestUserID {get; set ;}// target user name [ProtoMember (4)] public string DestUserName {get; set;} // chat Content, mainly text message [ProtoMember (5)] public string Content {get; set ;} // sending time [ProtoMember (6)] public DateTime SendTime {get; set;} [ProtoMember (7)] public IList <ImageWrapper> ImageList {get; set ;} // The following code is mainly used to prevent the list from being empty. If the list is empty and the following code is not added, serialization may cause a problem [Defaul TValue (false), ProtoMember (8)] private bool IsEmptyList {get {return ImageList! = Null & ImageList. count = 0;} set {if (value) {ImageList = new List <ImageWrapper> () ;}} public NewChatContract () {} public NewChatContract (string userID, string userName, string destUserID, string destUserName, string content, IList <ImageWrapper> imageList, DateTime sendTime) {this. userID = userID; this. userName = userName; this. destUserID = destUserID; this. destUserName = destUserName; this. content = content; this. imageList = imageList; this. sendTime = sendTime ;}}}
Modify the ChatControl control and add two buttons.
And add the relevant Code. For details, refer to the source code.
It should be noted that the Chat control uses the extended control of RichTextBox to determine whether the content in RichTextBox can be extracted, that is, including all text information and image information, then, it is sent as binary data,
But I am not familiar with this aspect. I have checked some articles and I have not finished it. If you are familiar with this aspect, please give me some advice.
Later, a work und was used to separate text content from image files.
Added a dictionary variable to the ChatControl control.
public Dictionary<string, Image> imageDict = new Dictionary<string, Image>();
When you insert an image, the image is added to the dictionary.
When a user sends chat information, the list of pictures in the dictionary is extracted for sending, and the image dictionary is cleared.
Click the relevant code when sending the chat information:
// The Image Dictionary public Dictionary <string, Image> imageDict = null; // List of Image packaging classes IList <ImageWrapper> imageWrapperList = new List <ImageWrapper> (); private void chatcontrol1_intosend (string content) {this. chatControl1.ShowMessage (Common. userName, DateTime. now, content, true); imageDict = this. chatControl1.imageDict; // Add the Image dictionary in the control to the foreach (KeyValuePair <string, Image> kv in imageDict) {ImageWra Pper newWrapper = new ImageWrapper (kv. key, kv. value); imageWrapperList. add (newWrapper);} // clear the image dictionary content in the control this. chatControl1.ClearImageDic (); // obtain the Connection p2pConnection = Common from the client Common. getUserConn (this. friendID); if (p2pConnection! = Null) {NewChatContract chatContract = new NewChatContract (); chatContract. userID = Common. userID; chatContract. userName = Common. userName; chatContract. destUserID = this. friendID; chatContract. destUserName = this. friendID; chatContract. content = content; chatContract. sendTime = DateTime. now; chatContract. imageList = imageWrapperList; p2pConnection. sendObject ("ClientChatMessage", chatContract); this. chatControl1.Focus (); LogInfo. logMessage ("send messages through p2p channel, current user ID is" + Common. userID + "current Tcp connection port number" + p2pConnection. connectionInfo. localEndPoint. port. toString (), "P2PINFO");} else {NewChatContract chatContract = new NewChatContract (); chatContract. userID = Common. userID; chatContract. userName = Common. userName; chatContract. destUserID = this. friendID; chatContract. destUserName = this. friendID; chatContract. content = content; chatContract. sendTime = DateTime. now; chatContract. imageList = imageWrapperList; Common. tcpConn. sendObject ("ChatMessage", chatContract); this. chatControl1.Focus (); LogInfo. logMessage ("server Forwarding Message", "P2PINFO ");}}
The transfer of images is a frequently-used function, which is often used in other programs. If you change it a little, you can take a picture on the client and then transfer it to the server for storage.
Thank you for coming.
A friend needs the SQL file of the database and made the following:
Data SQL file generation SQL data table content uses the CodeSmith template (more than 4.0 should be available) CodeSmith Template
"Mo Lu Xi Yan has your simple words." the problem mentioned by my friend "Sending images multiple times, the other party will receive multiple images" has been fixed, the imageWrapperList used to store images is cleared after each message is sent. Thank you for your attention.
IList<ImageWrapper> imageWrapperList = new List<ImageWrapper>();
Add this sentence
imageWrapperList.Clear();
Updated source code
Breeze IM3.2 has been released. Please refer to [source code sharing] breeze IM 3.2 to implement detailed procedures for registering new users
If you have any questions about performance, refer to the following article.
NetworkComms communication framework performance test