public void SendPrivateMessage(int pToImbHandle, PrivateMessage pm){ if (pToImbHandle <= 0) return; var channel = pToImbHandle + ServiceChannelExtentions; var content = pm.ConvertToStream().ToArray(); switch(pm.Action) { case PrivateMessageActions.Subscribe: var s = Services.FirstOrDefault(k => k.Id == pm.Id); LogImbService.LogMessage(String.Format("Request IMB client {0} that host service '{1}'({2}) add IMB client {4} to subscriptionlist (Action Subscribe)", AppState.Imb.ImbClientHandleToName(pToImbHandle), s != null ? s.Name : "-", pm.Id, channel, AppState.Imb.ImbClientHandleToName(pm.Sender))); break; case PrivateMessageActions.ServiceReset: var s1 = Services.FirstOrDefault(k => k.Id == pm.Id); LogImbService.LogMessage(String.Format("Request IMB client {0} that host service '{1}'({2}) to send (channel={3}) content of service to IMB client {4} (Action ListReset)", AppState.Imb.ImbClientHandleToName(pToImbHandle), s1 != null ? s1.Name : "-", pm.Id, channel, AppState.Imb.ImbClientHandleToName(pm.Sender))); break; } client.Imb.SignalBuffer(channel, 0, content); }
/// <summary> /// Send all content lists from a service to a client /// </summary> /// <param name="sender"></param> /// <param name="serviceId"></param> private void SendServiceReset(int sender /* IMB client handle */, Guid serviceId, int priority) { var s = Services.FirstOrDefault(k => k.Id == serviceId); var channel = sender + ServiceChannelExtentions; var sb = new StringBuilder(); sb.AppendLine(String.Format("{0}Send complete content of service '{1}' ({2}) to IMB client {3} (channel={4}) (action ListReset, {5} IMB messages used)", Environment.NewLine, s.Name, serviceId, AppState.Imb.ImbClientHandleToName(sender), channel, s.AllContent.Count())); int contentNumber = 0; foreach (var cl in s.AllContent) { try { contentNumber++; var pm = new PrivateMessage { Action = PrivateMessageActions.ListReset, Sender = client.Id, Id = serviceId }; using (var ms = new MemoryStream()) { var st = cl.ToList().Where(k => k.Priority <= priority).ToList(); Model.SerializeWithLengthPrefix(ms, st, typeof(List<BaseContent>), PrefixStyle.Base128, 72); pm.Content = ms.ToArray(); pm.Channel = cl.Id; if (cl == s.AllContent.First()) pm.ContentId = "First"; if (cl == s.AllContent.Last()) pm.ContentId = "Last"; client.Imb.SignalBuffer(channel, 0, pm.ConvertToStream().ToArray()); sb.AppendLine(string.Format("{0}.) Content types '{1}': ", contentNumber, cl.Id)); var count = 1; if (st.Count == 0) sb.AppendLine(string.Format("No items")); foreach (var x in st) { sb.AppendLine(string.Format("{1}.{2}){0}{3} ", Environment.NewLine, contentNumber, count, x.ToXml().ToString())); count++; } } } catch (Exception ex) { LogImbService.LogException(string.Format("SendServiceReset failed (broadcast service content on IMB)"), ex); } } LogImbService.LogMessage(sb.ToString()); }
private void SendPrivateMessage(int server, PrivateMessageActions action, Guid serviceId, string contentId, byte[] data, Guid ownerId, string channelName) { if (server <= 0) return; var channel = server + ServiceChannelExtentions; var pm = new PrivateMessage { Action = action, Sender = client.Id, Id = serviceId, ContentId = contentId, Content = data, OwnerId = ownerId, Channel = channelName }; var content = pm.ConvertToStream().ToArray(); client.Imb.SignalBuffer(channel, 0, content); }
// public void AddLocalDataServiceTemplate(string folder, string file) { // var idName = Path.GetFileNameWithoutExtension(file); // var guid = Guid.NewGuid(); // if (string.IsNullOrEmpty(idName)) return; // var ps = new PoiService { // IsLocal = true, // Folder = folder, // Id = guid, // Name = idName, // IsTemplate = true, // StaticService = false, // RelativeFolder = folder.Replace(baseFolder, string.Empty) // }; // ps.InitPoiService(); // Templates.Add(ps); // //CheckSettings(ps); // } // // public PoiService AddLocalDataServiceFromCsv(string folder, Mode _mode, string file, string originFolder = "", // bool autoStart = false) // { // PoiServiceImporterFromFileList poiServiceImporterFromFileList = PoiServiceImporterFromFileList.Instance; // IImporter<FileLocation, PoiService> suitableImporter = poiServiceImporterFromFileList.FirstOrDefault(importer => importer.DataFormatExtension.Equals("csv")); // // if (suitableImporter == null) // { // throw new NotImplementedException("Cannot find an importer for CSV files in the assembly."); // } // // IOResult<PoiService> ioResult = suitableImporter.ImportData(new FileLocation(Path.Combine(folder, file))); // if (ioResult.Successful) // { // return ioResult.Result; // } // else // { // throw ioResult.Exception; // } // } //private static void CheckSettings(Service ps) { // if (ps.SettingsList != null) return; // ps.SettingsList = ps.CreateContentList("settings", typeof(ServiceSettings)); // ps.SettingsList.Add(new ServiceSettings()); // ps.AllContent.Remove(ps.AllContent.FirstOrDefault(c => string.Equals(ps.SettingsList.Id, c.Id, StringComparison.InvariantCultureIgnoreCase))); // ps.AllContent.Add(ps.SettingsList); //} /// <summary> /// received message on private channel /// </summary> private void ReceivedPrivateMessage(TEventEntry aEvent, int aTick, int aBufferId, TByteBuffer aBuffer){ // REVIEW TODO fix: removed async var pm = PrivateMessage.ConvertByteArrayToMessage(aBuffer.Buffer); if (pm == null) { LogCs.LogWarning(String.Format("Received IMB message: Corrupt message! ", pm.Id, pm.Action)); return; } var s = Services.FirstOrDefault(k => k.Id == pm.Id); if (s == null) { LogCs.LogWarning(String.Format("Received IMB message: Service with GUID '{0}' is not found in servicelist (msg action is {1}). Ignore message. ", pm.Id, pm.Action)); return; } var reqClient = AppState.Imb.FindClient(pm.Sender); switch (pm.Action) { case PrivateMessageActions.RequestData: SendData(pm.Sender, s, pm.ContentId, pm.OwnerId, pm.Channel); break; case PrivateMessageActions.ResponseData: if ((s.store.SaveBytes(s.Folder, pm.ContentId, pm.Content, false))) // REVIEW TODO fix: removed await s.DataReceived(pm.ContentId, pm.Content); break; case PrivateMessageActions.SubscribeRequest: // TODO EV Why do you set server initialization to false? When adding a task, it is not synchronized anymore (RegisterContent is cancelled). //s.IsInitialized = false; if (!s.Subscribers.Contains(pm.Sender)) s.Subscribers.Add(pm.Sender); LogImbService.LogMessage(String.Format("Received IMB message: IMB client with handle {0} ({1}) requested to subscribe (join) service '{2}' ({3}) (add to service).", pm.Sender, (reqClient != null) ? reqClient.Name : "-", s.Name, pm.Id)); SendToImbBusSubscriptedToService(s.Id, pm.Sender); LogImbService.LogMessage(String.Format("IMB handles subscribed (joined) to service {0}: {1}", s.Name, s.SubscribedImbClientHandles)); if (reqClient != null && (AppState.Imb.ActiveGroup == null || !AppState.Imb.ActiveGroup.Clients.Contains(reqClient.Id))) Execute.OnUIThread( () => AppState.TriggerNotification(reqClient.Name + " has joined " + s.Name, image: reqClient.Image)); break; case PrivateMessageActions.UnsubscribeRequest: //s.IsInitialized = false; if (s.Subscribers.Contains(pm.Sender)) s.Subscribers.Remove(pm.Sender); SendPrivateMessage(pm.Sender, PrivateMessageActions.Unsubscribe, s.Id); var unsubClient = AppState.Imb.FindClient(pm.Sender); if (unsubClient != null) Execute.OnUIThread(() => AppState.TriggerNotification(unsubClient.Name + " has left " + s.Name, image: unsubClient.Image)); LogImbService.LogMessage(String.Format("Received IMB message: IMB client {0} requested to unsubscribe (unjoin) to service '{1}'({2}) (joined service).", AppState.Imb.ImbClientHandleToName(pm.Sender), s.Name, pm.Id)); LogImbService.LogMessage(String.Format("IMB handles subscribed (joined) to service '{0}'({1}): {2}", s.Name, s.Id, s.SubscribedImbClientHandles)); break; case PrivateMessageActions.ServiceReset: // requested for service reset int priority = 2; int.TryParse(pm.Channel, out priority); SendServiceReset(pm.Sender, s.Id, priority); //var resx = s.ToXml().ToString(); //SendPrivateMessage(pm.Sender,PrivateMessageActions.ResponseXml,s.Id,resx,Guid.Empty); break; case PrivateMessageActions.RequestXml: var res = s.ToXml().ToString(); SendPrivateMessage(pm.Sender, PrivateMessageActions.ResponseXml, s.Id, res, Guid.Empty); break; case PrivateMessageActions.ResponseXml: LogImbService.LogMessage(String.Format("Received IMB message: Recieved service XML definition for service {0} ({1}), Load XML into service.", s.Name, s.Id)); LogImbService.ToFile(String.Format("./logging/ReceivedServiceDefinition_{0}_{1}_{2}", s.Name, s.Id, DateTime.Now.Ticks), pm.ContentId); s.FromXml(pm.ContentId, s.Folder); s.TriggerInitialized(); break; case PrivateMessageActions.Subscribe: LogImbService.LogMessage(String.Format("Received IMB message: Subscribe request to subscribe to (join) service '{0}'({1}) acknowledged (mode={2})", s.Name, s.Id, mode)); s.Subscribe(mode); s.SubscribeServiceChannel(); //Subscribe(s); if (Subscribed != null) Subscribed(this, new ServiceSubscribeEventArgs { Service = s }); var npm = new PrivateMessage { Action = PrivateMessageActions.ServiceReset, Id = s.Id, Sender = client.Id, Channel = SyncPriority.ToString() }; SendPrivateMessage(pm.Sender, npm); break; case PrivateMessageActions.Unsubscribe: s.Unsubscribe(); s.UnSubscribeServiceChannel(); if (UnSubscribed != null) UnSubscribed(this, new ServiceSubscribeEventArgs { Service = s }); break; case PrivateMessageActions.ListReset: // receiving lists from server ListReset(s.Id, pm.Content, pm.Channel); if (pm.ContentId == "First") { count = 0; } count += pm.Content.Length; if (pm.ContentId == "Last") { var l = count; LogImbService.LogMessage(String.Format("Received last content for Service {0}", s.Id)); s.TriggerInitialized(); } LogImbService.LogMessage(String.Format("Received the content #{4} of service '{0}'({1}) from IMB client {2} (channel='{3}') (ListReset action).", s.Name, s.Id, AppState.Imb.ImbClientHandleToName(pm.Sender), pm.Channel, count)); break; case PrivateMessageActions.SendData: var f = s.Folder + @"\_Media\" + pm.ContentId; LogImbService.LogMessage(String.Format("IMB Message SendData received; store {0} bytes to location '{1}'", pm.Content.Length, f)); s.store.SaveBytes(f, pm.Content); break; } }