Software Engineering 2016.7.5 Daily
Today, my main job is to late the function of the client, connecting the client UI and the client socket, adding a file lock to the server to avoid the simultaneous operation of multiple threads on the same file.
Specific implementation of the work is:
Client function Setup:
The implementation of the communication function is completed on the client:
Complete the code that was vacant yesterday, and handle the message when it is received:
1 if(arrmsg[0] ==send_msg)2 {3 Receivemsgfromserver (msgreceive);4 }5 Else if(arrmsg[0] ==is_receive_msg)6 {7Application.Current.Dispatcher.Invoke (NewAction (Delegate8 {9MessageBox.Show ("Send Message succeeded");Ten })); One } A Else if(arrmsg[0] ==is_not_receive_msg) - { -Application.Current.Dispatcher.Invoke (NewAction (Delegate the { -MessageBox.Show ("[Error] failed to send message"); - })); - } + Else if(arrmsg[0] ==invalid_message) - { +Application.Current.Dispatcher.Invoke (NewAction (Delegate A { atMessageBox.Show ("[ERROR] Communication process error"); - })); - } - Else - { -Application.Current.Dispatcher.Invoke (NewAction (Delegate in { -MessageBox.Show ("[ERROR] Communication process error"); to })); +}
Among them, Receivemsgfromserver (String str), the concrete implementation is as follows:
1 #region---Receive Hostel history Message---2 /// <summary>3 ///Receive Message4 /// </summary>5 /// <param name= "msgreceive" ></param>6 Private voidReceivemsgfromserver (stringmsgreceive)7 {8Msghandler Msghandler = (msghandler) jsonconvert.deserializeobject (msgreceive,typeof(Msghandler));9 stringRoomid =Msghandler.roomid;Tenlist<string> msglist =msghandler.msglist; One AApplication.Current.Dispatcher.Invoke (NewAction (Delegate - { - tucaoWall.Document.Blocks.Clear (); the stringhostel = (string) Courselist.selecteditem; - if(A. Equals (roomid)) - foreach(stringMsginchmsglist) - { + //TODO: Add messages to the display box individually -Paragraph newparagraph =NewParagraph (); + AInlineUIContainer InlineUIContainer =NewInlineUIContainer () at { -Child =NewTextBlock () - { -Foreground =NewSolidColorBrush (colors.black), -TextWrapping =Textwrapping.wrap, -Text = msg +"\ r \ n" in } - }; to NewParagraph.Inlines.Add (inlineuicontainer); + - TucaoWall.Document.Blocks.Add (newparagraph); the } * $ }));Panax Notoginseng } - #endregion
Client UI connection to the client socket
The response to the response control is added, and the user clicks on a different button to interact with the server by invoking different methods. Because the code is too trivial, do not enumerate here.
The server side modifies some of the logic while adding a read-write lock to the file.
Since a new thread has been created on the server for each user, it is guaranteed to be synchronous at the receiving end of the message. However, there is no guarantee of the concurrency of sending messages, processing files, etc. (you can manipulate multiple files at the same time). Therefore, the related method is encapsulated as a class, creating a new object for each new linked user, so that each user can perform related operations on their own saved class objects without affecting each other. This section of the feature implementation code is as follows:
To add a dictionary of processing objects from the User IP index
publicstatic dictionary<stringnew dictionary<string, Handler> ();
Methods for handling object handler encapsulation include
Public void Checkroomlist (string s_roomlist); Public void Addmsgtofile (stringstring msg); Public void Invalidmsg (string clientip); Public void SendMessage (stringbytestring msg);
The handler object that corresponds to a specific IP method is
1 if(msgreceiver[0] ==check_room_list)2 Dicthandler[socketkey]. Checkroomlist (msg);3 Else if(msgreceiver[0] ==request_room_msg)4 Dicthandler[socketkey]. Getroommsg (Socketkey, msg);5 Else if(msgreceiver[0] ==send_msg)6 Dicthandler[socketkey]. Addmsgtofile (Socketkey, msg);7 Else if(msgreceiver[0] ==DISCONNECT)8 Removeofflineuser (socketkey);9 ElseTenDicthandler[socketkey]. Invalidmsg (Socketkey);
After implementing the above functions, also need to deal with the file read and write synchronization problems, the same file can not be multiple threads at the same time, so in order to solve this problem need to add a read-write lock for each file, to control the file read and write synchronization problems.
Create a dictionary in your program that is indexed by file names to read-write locks
Public Static dictionary<stringnew dictionary<stringobject> ();
Concurrency control is required for each operation of the file, and the use of the corresponding read-write lock is detected using the following example:
1 Lock(Server.dictlocker[room])2 {3FileStream fs =NewFileStream (Roomfile, filemode.create);4 FS. Close ();5 6 Lock(server.dictlocker[" the"])7 {8 stringRomfile ="Room.txt";9 TenFileStream f =File.openwrite (romfile); One AF.position =f.length; - - byte[] writemsg = Encoding.UTF8.GetBytes (room+"\ r \ n"); the -F.write (Writemsg,0, writemsg.length); - - f.close (); + } -}
Through the above method, the file read and write control is realized.
Software Engineering 2016.7.5 Daily