36 0 373KB
Ministerul Educaţiei al Republicii Moldova Universitatea Tehnică a Moldovei
Catedra: Automatică și Tehnologii Informaționale
RAPORT Lucrare de laborator Nr.1 la disciplina Programarea Aplicațiilor Distribuite Tema: Agent de mesagerie – Message Broker
A efectuat:
st. gr. SI-121 A. Gurițanu
A verificat:
lect. univ. I.Antohi
Chişinău 2015
Scopul lucrării: integrarea bazată pe agenți de mesaje care ar permite o comunicare asincronă dintre componentele distribuite ale unui sistem. Sarcina lucrării: Considerând brokerul o formă generalizată a medierii dintre componentele distribuite, se propune implementări ale rutării sau construirii de mesaje în conformitate cu șabloanele menționate de Gregor Hohpe în [3], care sunt grupate în câteva secțiuni: a. Messaging Systems, b. Messaging Channels, c. Message Constructions, d. Message Routing, e. Message Transformation, f. Messaging endpoints, g. System management. Implementare: La efectuarea acestului laborator, am implementat un sistem de tip mesagerie instantanee. Sistemul are urmatoarea structură: Aplicația Web
Repositories
Domain Models
Services
Infrastructure
Broker
MongoDB
Fig.1 Structura sistemului 1. Message Channel (Messaging Systems) În cadrul sistemului aplicațiile web comunică cu Broker-ul. Broker-ul poate primit mesaje de la utilizatori și transmite mesaje destinatarilor, astfel el reprezintă un mediator între diferiți utilizatori ai sistemului. 2. Message Translator (Messaging Systems) În cadrul sistemului se efectuiază translarea mesajelor. Broker-ul primește/transmite mesaje de tip Json și le salvează în baza de date în formatul Bson, specific SGBD MongoDB. 3. Publish-Subscribe Channel (Messaging Channels) Utilizatorii sunt notificați despre mesajele noi pe care le primesc de la alți utilizatori, precum și notificați despre faptul, că au cereri de prietenie din partea altor utilizatori. 4. Dead Letter Channel (Messaging Channels) Toate mesajele din cadrul sistemului, precum și cererile de prietenie sunt salvate în baza de date, respectiv în cadrul sistemului nu există pierderi de mesaje. 5. Correlation Identifier (Message Construction)
Utilizînd numele de utilizator în cadrul sistemului, entitățile sunt identificate. Atunci cînd utilizatorii se autentifică, aceștea sunt salvați întro colecție specială de date, care conține atît numele cît și id-ul de conexiune din cadrul Hub-ului. 6. Content-Based Router (Message Routing) În dependență de cîmpul mesajului „ConectionID”, mesajul poate fi transmis către un unic utilizator și salvat în baza de date sau transmis tuturor utilizatorilor online. 7. Content Enricher (Message Transformation) La autentificarea în sistem, utilizatorilor le sunt transmise datele privind lista de prieteni și mai apoi doar sunt transmise, la dorință și mesajele din conversația dorită. Codul sursă „BrokerHub”: using using using using using using using using using using using
System; System.Collections.Generic; System.Linq; Chat.Managers.FriendRequest; Chat.Managers.Interface.AuthenticationManager; Microsoft.AspNet.SignalR; Microsoft.AspNet.SignalR.Hubs; Models.ActiveUser; Models.Conversation; Models.FriendRequest; Models.User;
namespace Broker { [HubName("brokerHub")] public class BrokerHub : Hub { private readonly Chat.Managers.Interface.UserManager.IManager userManager; private readonly Chat.Managers.Interface.AuthenticationManager.IManager authenticationManager; private readonly Chat.Managers.Interface.ActiveUserManager.IManager activeUserManager; private readonly Chat.Managers.Interface.FriendRequest.IManager friendRequestManager; private readonly Chat.Managers.Interface.Conversation.IManager conversationManager; public BrokerHub() { userManager = new Chat.Managers.UserManager.Manager(); authenticationManager = new Chat.Managers.AuthenticationManager.Manager(); activeUserManager = new Chat.Managers.ActiveUserManager.Manager(); friendRequestManager = new Chat.Managers.FriendRequest.Manager(); conversationManager = new Chat.Managers.Conversation.Manager(); } public void Send(ChatMessage message) { if (message.ConversationID == null) { Clients.All.addMessage(message.Sender, message.Text); } else { conversationManager.AddMessage(message.ConversationID.Value, new Message { Sender = message.Sender, Text = message.Text }); ActiveUser user = activeUserManager.FindBy(message.Receiver); if (user != null) { Clients.Client(user.ConnectionID).addMessage(message.Sender, message.Text, message.ConversationID);
Clients.Caller.addMessage(message.Sender, message.Text, message.ConversationID); } } } public void GetFriendsList(string user) { Clients.All.recieveFriendsList(); } public void AddFriend(FriendRequest request) { if (request.State == RequestState.Pending) { friendRequestManager.Add(request); ActiveUser user = activeUserManager.FindBy(request.RequestedUser); if (user != null) { Clients.Client(user.ConnectionID).recievePendingUsersList( new FriendRequest[]{request}); } } else { friendRequestManager.Update(request); Friend friend = new Friend() { Name = request.UserName, ConversationID = Guid.NewGuid() }; userManager.AddFriend(request.RequestedUser, friend); userManager.AddFriend(request.UserName, new Friend { ConversationID = friend.ConversationID, Name = request.RequestedUser }); conversationManager.Add(new Conversation { ID = friend.ConversationID }); } } public void LogIn(string user, string password) { bool isValidUser = authenticationManager.IsValidUser(new UserCredentials { UserName = user, Password = password }); if (isValidUser) { Clients.Caller.recieveFriendsList(userManager.GetFriends(user)); activeUserManager.Add(new Models.ActiveUser.ActiveUser() { UserName = user, ConnectionID = Context.ConnectionId });
Clients.Caller.recievePendingUsersList(friendRequestManager.FindBy(user).ToArray()); } } public void LogOut(string user) { activeUserManager.Remove(user); } public void Register(User user) { userManager.Register(user); } public void SearchUsers(string key) { User[] users = userManager.Search(key); ActiveUser currentUser = activeUserManager.GetBy(Context.ConnectionId); Clients.Caller.recieveUsersList(users.Where(x => x.UserName != currentUser.UserName)); } public void GetMessages(Guid conversationID, int messageNumber) { List messages = conversationManager.GetMessages(conversationID, messageNumber); Clients.Caller.receiveOldMessages(conversationID, messages); } public override System.Threading.Tasks.Task OnDisconnected(bool stopCalled) { ActiveUser user = activeUserManager.GetBy(Context.ConnectionId); activeUserManager.Remove(user.UserName); return base.OnDisconnected(stopCalled); } } }
Rezultatele afișării:
Fig.2 Pagina de autentificare
Fig.3 Pagina cu mesaje
Fig.4 Pagina de adăugare a prietenilor
Concluzie: În urma efectuării aceste lucrări de laborator am implementat un Broker, care are funcția de asigurare a comunicației între utilizatorii sistemului. Am utilizat o bază de date MongoDB pentru a stoca datele persistent în formatul de date Bson. Am implementat toate 7 șabloane enumerate în condiție.
Bibliografie: 1. Sean Chambers, Simone Chimoretta, 31 days refactoring [ Resursă electronică].-Regim de acces: http://lostechies.com/wp-content/uploads/2011/03/31DaysRefactoring.pdf; 2. Tony Northgroup, Microsoft.NET Framework – Application Development Foundation 2nd edition , Library of Congress Control Number: 2008935429; 3. Kristina Cbodorow, 50 Tips & tricks for MongoDB Developers, ISBM: 978-1-449-30461-4; 4. http://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections - maparea utilizatorilor la conexiunile existente cu păstrare persistentă.