UCMA 3.0 API Conferencing Error : Cannot join a different conference after receiving a conference invitation or conference escalation request - lync-2010

We have a UCMA 3.0 based application/bot that matches end users with experts. It migrates incoming one-one chat requests from end users into a multi user conference and then invites experts into the resulting multi user conference. The application itself continues to be a participant in the conference. At any given time, there may be several such conferences being brokered by our application but only one per end user. However, a single expert may be participating in more than one conference at the same time.
In our application logs we occasionally see the following exception.
Error in Conference Migration conf call # 63809878 ,Address :sip:xxxxxx#xxx.com;gruu;opaque=app:conf:focus:id:TQRREACE System.InvalidOperationException: Cannot join a different conference after receiving a conference invitation or conference escalation request.
at Microsoft.Rtc.Collaboration.ConferenceSession.VerifyAndGetConferenceAddress(String conferenceUri, String parameterName)
at Microsoft.Rtc.Collaboration.ConferenceSession.BeginJoinCommon(String conferenceUri, ConferenceJoinOptions options, AsyncCallback userCallback, Object state)
at Microsoft.Rtc.Collaboration.ConferenceSession.BeginJoin(String conferenceUri, ConferenceJoinOptions options, AsyncCallback userCallback, Object state)
at a(String A_0, String A_1, String A_2, Boolean A_3, Boolean A_4)
Below is the code snippet used to make conference. Previously this site was an OCS 2007 R2 Installation and was migrated to Lync 2010 Server.
Site is running in mixed mode. It occurs only on production server and we are not able to generate this exception on dev server, we
have tested it after generating more than 15 conferences simultaniously but no luck.
private void CreateAdHohConf(string user1Uri, string user2uri, string subject)
{
Exception exception = null;
// Create conference scheduling details for the conference.
ConferenceScheduleInformation scheduleInfo = new ConferenceScheduleInformation();
// Restrict the conference to invited users only.
scheduleInfo.AccessLevel = ConferenceAccessLevel.Everyone;
// Set a subject for the conference.
scheduleInfo.Subject = subject;
scheduleInfo.Description = subject;
scheduleInfo.ConferenceId = ConferenceServices.GenerateConferenceId();
scheduleInfo.ExpiryTime = System.DateTime.Now.AddHours(8);
scheduleInfo.IsPasscodeOptional = true;
scheduleInfo.PhoneAccessEnabled = false;
// Don't automatically assign a leader.
scheduleInfo.AutomaticLeaderAssignment = AutomaticLeaderAssignment.Everyone;
// Add the caller and recipient as participants.
scheduleInfo.Participants.Add(new ConferenceParticipantInformation("sip:" + user1Uri, ConferencingRole.Leader));
scheduleInfo.Participants.Add(new ConferenceParticipantInformation("sip:" + user2uri, ConferencingRole.Leader));
scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.ApplicationSharing));
scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.InstantMessaging));
scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.AudioVideo));
scheduleInfo.Mcus.Add(new ConferenceMcuInformation(McuType.Meeting));
//Scheduling conference
ConferenceServices objLocalConfSvc = lyncAgent.LocalEndpoint.ConferenceServices;
Conference confSession = null;
objLocalConfSvc.BeginScheduleConference(scheduleInfo,
result =>
{
try
{
confSession = objLocalConfSvc.EndScheduleConference(result);
}
catch (RealTimeException rtex)
{
exception = rtex;
}
catch (Exception ex)
{
exception = ex;
}
finally
{
_waitForConferenceScheduling.Set();
}
}, objLocalConfSvc);
_waitForConferenceScheduling.WaitOne();
//Begin Join conference
ConferenceSession objLocalConfSession=this.call.Conversation.ConferenceSession;
try
{
ConferenceJoinOptions joinOptions = new ConferenceJoinOptions() { CanManageLobby = false, JoinMode = JoinMode.Default };
objLocalConfSession.BeginJoin(new RealTimeAddress(confSession.ConferenceUri).Uri, joinOptions,
result => {
try
{
objLocalConfSession.EndJoin(result);
}
catch (Exception ex)
{
exception = ex;
}
finally
{
//Again, for sync. reasons.
_waitForConferenceJoin.Set();
}
}
, this.call.Conversation.ConferenceSession);
// Wait until join completes.new RealTimeAddress(this._conference.ConferenceUri).Uri,
_waitForConferenceJoin.WaitOne();
}
catch (InvalidOperationException ioex)
{
exception = ioex;
}
catch (Exception ex)
{
exception = ex;
}
//Begin Escalation
Conversation objLocalConv= this.call.Conversation;
try
{
objLocalConv.BeginEscalateToConference(
result =>
{
try
{
objLocalConv.EndEscalateToConference(result);
}
catch (Exception ex)
{
exception = ex;
}
finally
{
//Sync It
_waitForEscalation.Set();
}
}
, objLocalConv);
// Wait until escalation completes.
_waitForEscalation.WaitOne();
}
catch (InvalidOperationException ioex)
{
exception = ioex;
}
catch (Exception ex)
{
exception = ex;
}
finally
{
if (exception != null)
{
lyncAgent.Logger.Error( "Error in Conference Migration conf call # " + GetHashCode() + " , Address :" + confSession.ConferenceUri , exception);
}
}
}
Please suggest what could be the possible problem on priority basis.
Thanks in advance.

Does this method reside in an object where it is possible that it will be called by multiple sources at the same time?
If so, using what appears to be a class level variable like _waitForConferenceScheduling could be problematic. Thread A could end up accidentally letting Thread B proceed before Thread B's async action is actually completed. So Thread B could call .BeginEscalate before .EndJoin was called.
When I write UCMA code, I generally use nested callbacks to prevent this type of thing from happening.
Other than that, I'd recommend you run OCSLogger on your application server and the Lync Front End server to gather SIPStack, S3 and Collaboration logs. Looking at the actual SIP messages in detail will provide some clues.
You'd be looking for an INVITE to the conference and the response back to that INVITE.

We managed to detect the reason. It happens if any one in the participant list have already added any contact for meeting in conversation with our endpoint.

Related

Can’t write amount of data to kepware

When I write data to kepware server by milo, sometimes some data can not be written successfully. But the server returned
StatusCode{name=Good, value=0x00000000, quality=good}
The server did not display the data which I had written.
Thanks in advance for any help
Single thread did not work.
Create new client when start to write data.
There is only one client which responds to writing.
All of these failed.
mWriteClient = new OPCUAClientRunner(KSOPCUASubscription.this).createClient();
mWriteClient.connect().get();
} catch (Exception e) {
e.printStackTrace();
logger.error("OPCUAClient connect Exception", e);
return ;
}
logger.info("Wrote identifier: " + identifier);
List<NodeId> nodeIds = ImmutableList.of(new NodeId(namespaceIndex, identifier));//Int32"t|bbb"
Variant v = new Variant(value);
// don't write status or timestamps
DataValue dv = new DataValue(v, null, null);
logger.info("OPCUAClient begin write");
// write asynchronously....
CompletableFuture<List<StatusCode>> f =
mWriteClient.writeValues(nodeIds, ImmutableList.of(dv));
// ...but block for the results so we write in order
List<StatusCode> statusCodes = null;
try {
statusCodes = f.get();
} catch (InterruptedException e) {
e.printStackTrace();
logger.error("OPCUAClient write get response Exception", e);
} catch (ExecutionException e) {
e.printStackTrace();
logger.error("OPCUAClient write get response Exception", e);
}
StatusCode status = statusCodes.get(0);
logger.info("Wrote status: " + status.toString());
if (status.isGood()) {
logger.info("Wrote '{}' to nodeId={}", v, nodeIds.get(0));
}
Unless you're not actually writing the value you claim to be writing, a StatusCode of Good from the server means you're not doing anything wrong on the client side.
Maybe you can capture the exchange with Wireshark to further prove the issue is on the server side.

How to know who received a message in a MUC room

For my thesis, I am using Smack to log a XMPP network that uses the MUC module.
Another software is currently sending IoT sensor data into different MUC rooms.
I'd like to know for every message sent into a MUC room, which users were in that room at the time of the message. Is this possible? I could use a messageListener to every muc room, however the listener only receives a message as an argument. Therefore I could not know who is logged into the room inside the listener method.
you can get all muc message in StanzaListener in xmpp. Please follow few steps to done this
Step 1. Declare as a global variables
ChatManagerListener chatListener;
Chat chat;
StanzaListener packetListener;
Step 2. Use this code in oncreate or in fragment
Note: Make sure you have connected with chat server.
packetListener = new StanzaListener() {
#Override
public void processPacket(Stanza packet) throws SmackException.NotConnectedException, InterruptedException {
if (packet instanceof Message) {
final Message message = (Message) packet;
}
}
};
XMPP.getInstance().getConnection(acitiviy)).addAsyncStanzaListener(stanzaListener, null);
ServiceDiscoveryManager sdm = ServiceDiscoveryManager
.getInstanceFor(XMPP.getInstance().getConnection(acitiviy)));
sdm.addFeature("jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/si");
sdm.addFeature("http://jabber.org/protocol/disco#info");
sdm.addFeature("jabber:iq:privacy");
Step 3. Methods for one to one chat purposer
void sendMessage(String message) {
if (chat != null) {
try {
chat.sendMessage(message);
Message msg = new Message();
msg.setTo(JidCreate.bareFrom(jid));
msg.setFrom(XMPP.getInstance().getConnection(acitiviy)
.getUser());
ChatStateExtension ext = new ChatStateExtension(
ChatState.paused);
msg.addExtension(ext);
lastComposing = System.currentTimeMillis();
chat.sendMessage(msg);
} catch (SmackException.NotConnectedException e) {
} catch (Exception e) {
}
}
}
Step 4. On destroy
XMPP.getInstance().getConnection(acitiviy)).removeAsyncStanzaListener(stanzaListener);
Hope this will help you and if you want more information take a look from here. Thankyou
Nothing prervents you from calling Multi UserCaht.getParticipants() from within the listener. But be warned: If your goal is to determine the other receivers of receivers, then this approach is fragile. I also suggest to think about using PubSub instead of MUC for your IoT use case.

UWP streamsocket ping networktimer issues

I have a StreamSocket in UWP and I send my messages like this using a DataWriter object using the StoreAsync() method:
public static async Task<bool> SendNetworkMessage(NetworkMember member, NetworkMessage message)
{
DataWriter writer = member.DataWriter;
//Check that writer is not null
if (writer != null)
{
try
{
//Serialize Message
string stringToSend = SerializeObject<NetworkMessage>(message);
//Send Message Length
writer.WriteUInt32(writer.MeasureString(stringToSend));
//Send Message
writer.WriteString(stringToSend);
await writer.StoreAsync();
return true;
}
catch (Exception e)
{
Debug.WriteLine("DataWriter failed because of " + e.Message);
Debug.WriteLine("");
Disconnect(member);
OnMemberDisconnectedEvent(member);
return false;
}
}
else { return false; }
}
All is well, the only problem is that I don't know if a connection went down.
Now I want to check my connection using a DispatcherTimer like this:
private static async void NetworkTimer_Tick(object sender, object e)
{
foreach (NetworkMember member in networkMemberCollection)
{
if (member.Connected == true && member.Disconnecting == false)
{
await SendNetworkMessage(member, new PingMessage());
}
}}
However, this is causing timing issues which is causing ObjectDisposedExceptions on the DataWriter. It seems that the DispatcherTimer thread cannot use the StreamSocket when I send a message from a different thread. My question is: How can I make sure the Ping is sent each time but that SendNetworkMessage operations are done in order instead of overlapping?
Thanks
It seems that the DispatcherTimer thread cannot use the StreamSocket when I send a message from a different thread.
How can I make sure the Ping is sent each time but that SendNetworkMessage operations are done in order instead of overlapping?
It's possible, and I think your code using foreach and await operation can ensure the work of sending message in order.
the only problem is that I don't know if a connection went down.
If you want to know if the connection went down, you can refer to Handling WinRT StreamSocket disconnects (both server and client side).

Class MessagingException not working as I think it should

I'm developing a web application that sends an email and has to check, that, in fact this mail has been delivered from my application side as much as possible in few seconds (I don't think you can do more than getting that the email has been delivered to email server, if that email server later cannot later send that email to the user that uses it because it has its inbox full or another situation like this, I think it cannot be helped, although if there's some way I'd like to know about it).
Anyway one thing I think could be checked without problems is if the email address doesn't exist as that gives an inmediate response, according to what I've read this could be done with class MessageException, but I've the following code:
String email=Utils.parseString(req,"email");
[....]
Properties props = new Properties();
props.put("mail.smtp.host", "smtp.gmail.com");
props.put("mail.smtp.starttls.enable","true");
props.put("mail.smtp.EnableSSL.enable","true");
Session s = Session.getInstance(props, null);
MimeMessage message = new MimeMessage(s);
try {
InternetAddress from = new InternetAddress(emailadressthatworks);
message.setFrom(from);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return;
}
try {
InternetAddress to = new InternetAddress(email);
message.addRecipient(Message.RecipientType.TO, to);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
resp.sendRedirect("webpage.jsp");
return;
}
try {
message.setSubject("Subject");
message.setText("message");
Transport.send(message);
} catch (MessagingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
resp.sendRedirect("webpage.jsp");
return;
}
[....]
And whatever random String I asign to email it never throws an MessagingException in Transport.send(message); so I can redirect it to another jsp web page when I think it should according to what I have read.
Might I be missing something or is it that this class cannot detect that things?
Thanks for your help.
Use the strict InternetAddress constructor and call message.saveChanges() to perform the validation. See
Content-Type syntax check throws exception too late for more details.
See this JavaMail FAQ entry.
Also, it's up to your mail server whether it tries to detect some kinds of errors immediately or whether it queues all requests and only checks for errors later.

Monotouch data sync - why does my code sometimes cause sqlite errors?

I have the following calls (actually a few more than this - it's the overall method that's in question here):
ThreadPool.QueueUserWorkItem(Database.Instance.RefreshEventData);
ThreadPool.QueueUserWorkItem(Database.Instance.RefreshLocationData);
ThreadPool.QueueUserWorkItem(Database.Instance.RefreshActData);
1st point is - is it OK to call methods that call WCF services like this? I tried daisy chaining them and it was a mess.
An example of one of the refresh methods being called above is (they all follow the same pattern, just call different services and populate different tables):
public void RefreshEventData (object state)
{
Console.WriteLine ("in RefreshEventData");
var eservices = new AppServicesClient (new BasicHttpBinding (), new EndpointAddress (this.ServciceUrl));
//default the delta to an old date so that if this is first run we get everything
var eventsLastUpdated = DateTime.Now.AddDays (-100);
try {
eventsLastUpdated = (from s in GuideStar.Data.Database.Main.Table<GuideStar.Data.Event> ()
orderby s.DateUpdated descending
select s).ToList ().FirstOrDefault ().DateUpdated;
} catch (Exception ex1) {
Console.WriteLine (ex1.Message);
}
try {
eservices.GetAuthorisedEventsWithExtendedDataAsync (this.User.Id, this.User.Password, eventsLastUpdated);
} catch (Exception ex) {
Console.WriteLine ("error updating events: " + ex.Message);
}
eservices.GetAuthorisedEventsWithExtendedDataCompleted += delegate(object sender, GetAuthorisedEventsWithExtendedDataCompletedEventArgs e) {
try {
List<Event> newEvents = e.Result.ToList ();
GuideStar.Data.Database.Main.EventsAdded = e.Result.Count ();
lock (GuideStar.Data.Database.Main) {
GuideStar.Data.Database.Main.Execute ("BEGIN");
foreach (var s in newEvents) {
GuideStar.Data.Database.Main.InsertOrUpdateEvent (new GuideStar.Data.Event {
Name = s.Name,
DateAdded = s.DateAdded,
DateUpdated = s.DateUpdated,
Deleted = s.Deleted,
StartDate = s.StartDate,
Id = s.Id,
Lat = s.Lat,
Long = s.Long
});
}
GuideStar.Data.Database.Main.Execute ("COMMIT");
LocationsCount = 0;
}
} catch (Exception ex) {
Console.WriteLine("error InsertOrUpdateEvent " + ex.Message);
} finally {
OnDatabaseUpdateStepCompleted (EventArgs.Empty);
}
};
}
OnDatabaseUpdateStepCompleted - just iterates an updateComplete counter when it's called and when it knows that all of the services have come back ok it removes the waiting spinner and the app carries on.
This works OK 1st time 'round - but then sometimes it doesn't with one of these: http://monobin.com/__m6c83107d
I think the 1st question is - is all this OK? I'm not used to using threading and locks so I am wandering into new ground for me. Is using QueueUserWorkItem like this ok? Should I even be using lock before doing the bulk insert/update? An example of which:
public void InsertOrUpdateEvent(Event festival){
try {
if (!festival.Deleted) {
Main.Insert(festival, "OR REPLACE");
}else{
Main.Delete<Event>(festival);
}
} catch (Exception ex) {
Console.WriteLine("InsertOrUpdateEvent failed: " + ex.Message);
}
}
Then the next question is - what am I doing wrong that is causing these sqlite issues?
w://
Sqlite is not thread safe.
If you want to access Sqlite from more than one thread, you must take a lock before you access any SQLite related structures.
Like this:
lock (db){
// Do your query or insert here
}
Sorry, no specific answers, but some thoughts:
Is SqlLite even threadsafe? I'm not sure - it may be that it's not (to the wrapper isn't). Can you lock on a more global object, so no two threads are inserting at the same time?
It's possible that the MT GC is getting a little overenthusiastic, and releasing your string before it's been used. Maybe keep a local reference to it around during the insert? I've had this happen with view controllers, where I had them in an array (tabcontrollers, specificially), but if I didn't keep an member variable around with the reference, they got GC'ed.
Could you get the data in a threaded manner, then queue everything up and insert them in a single thread? Atleast as a test anyway.