public static void TerminateBoshSession(HttpListenerContext ctx, Body body, string condition) { if (ctx == null || ctx.Response == null) return; if (body == null) body = new Body(); try { body.Type = BoshType.terminate; if (!string.IsNullOrEmpty(condition)) body.SetAttribute("condition", condition); SendAndCloseResponse(ctx, body.ToString()); log.DebugFormat("TerminateBoshSession body: {0}", body); } catch (Exception e) { try { ctx.Response.Close(); } catch { } log.ErrorFormat("Error TerminateBoshSession body: {0}\r\n{1}", body, e); } }
private void InvokeStreamStart(Body body) { var stream = new Stream(); stream.Prefix = Uri.PREFIX; stream.Namespace = Uri.STREAM; stream.Version = body.Version; stream.Language = body.GetAttribute("lang"); stream.To = body.To; var handler = XmppStreamStart; if (handler != null) handler(this, new XmppStreamStartEventArgs(Id, stream, Uri.CLIENT)); }
private void SendAnswer(Body body, HttpListenerContext ctx) { try { lock (sendBuffer) { foreach (var node in sendBuffer) { body.AddChild(node); if (node.Namespace == Uri.STREAM) body.SetAttribute("xmlns:stream", Uri.STREAM); } if (closed) body.Type = BoshType.terminate; BoshXmppHelper.SendAndCloseResponse(ctx, body.ToString(), true, null); sendBuffer.Clear(); log.DebugFormat("Connection {0} Send buffer:\r\n{1}", Id, body); } } catch (Exception e) { //BUG: Я думаю баг тут из за обрыва соединения при говенном кач-ве соединения. log.DebugFormat("Connection {0} Error send buffer: {1}", Id, e); Close(); } }
private Body WriteBodyHeaders(Body body) { if (string.IsNullOrEmpty(body.Sid)) { body.Sid = Id; body.Secure = false; } body.Ack = body.Rid != 0 ? body.Rid : rid; body.RemoveAttribute("rid"); body.To = null; if (body.HasAttribute("xmpp:version") || body.HasAttribute("xmpp:restart")) { body.SetAttribute("xmlns:xmpp", "urn:xmpp:xbosh"); } body.RemoveAllChildNodes(); return body; }
private void ReadBodyHeaders(Body body) { rid = body.Rid; if (0 < body.Wait) waitPeriod = TimeSpan.FromSeconds(body.Wait); if (0 < body.Inactivity) inactivityPeriod = TimeSpan.FromSeconds(body.Inactivity); }
private bool ValidateBody(Body body) { if (0 < body.Window) window = body.Window; if (0 < body.Polling) window = body.Polling; if (closed) return false; if (rid != 0 && window < Math.Abs(body.Rid - rid)) return false; return true; }
public void ProcessBody(Body body, HttpListenerContext ctx) { try { IdleWatcher.UpdateTimeout(Id, TimeSpan.MaxValue); if (body == null) throw new ArgumentNullException("body"); if (ctx == null) throw new ArgumentNullException("httpContext"); log.DebugFormat("Start process body connection {0}\r\n{1}\r\n", Id, body); if (!ValidateBody(body)) { BoshXmppHelper.TerminateBoshSession(ctx, "bad-request"); return; } if (body.Type == BoshType.terminate) { Close(); ctx.Response.Close(); return; } waitDrop.Set(); waitDrop.Reset(); ReadBodyHeaders(body); if (string.IsNullOrEmpty(body.Sid) || body.XmppRestart) { InvokeStreamStart(body); } foreach (var node in body.ChildNodes) { if (node is Element) InvokeStreamElement((Element)node); } WriteBodyHeaders(body); log.DebugFormat("Connection {0} WAIT ...", Id); var waitResult = WaitAnswerOrDrop(); if (waitResult == WaitResult.Success) { log.DebugFormat("Connection {0} send answer", Id); SendAnswer(body, ctx); } else if (waitResult == WaitResult.Timeout) { log.DebugFormat("Connection {0} drop by timeout", Id); BoshXmppHelper.SendAndCloseResponse(ctx, new Body().ToString()); } else { log.DebugFormat("Connection {0} terminate", Id); BoshXmppHelper.TerminateBoshSession(ctx, body); } } finally { IdleWatcher.UpdateTimeout(Id, inactivityPeriod); } }
public static void TerminateBoshSession(HttpListenerContext ctx, Body body) { TerminateBoshSession(ctx, body, null); }