WebSocket 最简单的用法

  1 package com.uptop.websocket;
  2
  3 import javax.websocket.*;
  4 import javax.websocket.server.ServerEndpoint;
  5
  6 import java.io.IOException;
  7 import java.util.concurrent.CopyOnWriteArraySet;
  8
  9
 10 /**
 11  * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
 12  * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
 13  * @author uptop
 14  */
 15 @ServerEndpoint("/websocket")
 16 public class WebSocketTest {
 17     //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
 18     private static int onlineCount = 0;
 19
 20     //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
 21     public static CopyOnWriteArraySet<WebSocketTest> webSocketSet = new CopyOnWriteArraySet<WebSocketTest>();
 22
 23     //与某个客户端的连接会话,需要通过它来给客户端发送数据
 24     private Session session;
 25
 26     /**
 27      * 连接建立成功调用的方法
 28      *
 29      * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
 30      */
 31     @OnOpen
 32     public void onOpen(Session session) {
 33         this.session = session;
 34         webSocketSet.add(this);     //加入set中
 35         addOnlineCount();           //在线数加1
 36         System.out.println("有新连接加入!当前在线人数为" + getOnlineCount());
 37     }
 38
 39     /**
 40      * 连接关闭调用的方法
 41      */
 42     @OnClose
 43     public void onClose() {
 44         webSocketSet.remove(this);  //从set中删除
 45         subOnlineCount();           //在线数减1
 46         System.out.println("有一连接关闭!当前在线人数为" + getOnlineCount());
 47     }
 48
 49     /**
 50      * 收到客户端消息后调用的方法
 51      *
 52      * @param message 客户端发送过来的消息
 53      * @param session 可选的参数
 54      */
 55     @OnMessage
 56     public void onMessage(String message, Session session) {
 57         System.out.println("来自客户端的消息:" + message);
 58         //群发消息
 59         for (WebSocketTest item : webSocketSet) {
 60             try {
 61                 item.sendMessage(message);
 62             } catch (IOException e) {
 63                 e.printStackTrace();
 64                 continue;
 65             }
 66         }
 67     }
 68
 69     /**
 70      * 发生错误时调用
 71      *
 72      * @param session
 73      * @param error
 74      */
 75     @OnError
 76     public void onError(Session session, Throwable error) {
 77         System.out.println("发生错误");
 78         error.printStackTrace();
 79     }
 80
 81     /**
 82      * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
 83      *
 84      * @param message
 85      * @throws IOException
 86      */
 87     public void sendMessage(String message) throws IOException {
 88         this.session.getBasicRemote().sendText(message);
 89
 90     }
 91
 92     public static synchronized int getOnlineCount() {
 93         return onlineCount;
 94     }
 95
 96     public static synchronized void addOnlineCount() {
 97         WebSocketTest.onlineCount++;
 98     }
 99
100     public static synchronized void subOnlineCount() {
101         WebSocketTest.onlineCount--;
102     }
103
104
105     public void sendMsg(String msg) {
106         for (WebSocketTest item : webSocketSet) {
107             try {
108                 item.sendMessage(msg);
109             } catch (IOException e) {
110                 e.printStackTrace();
111                 continue;
112             }
113         }
114     }
115 }
/* SockJS client, version 0.3.4, http://sockjs.org, MIT License

Copyright (c) 2011-2012 VMware, Inc.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/

// JSON2 by Douglas Crockford (minified).
var JSON;
JSON || (JSON = {}), function() {
    function str(a, b) {
        var c, d, e, f, g = gap,
            h, i = b[a];
        i && typeof i == "object" && typeof i.toJSON == "function" && (i = i.toJSON(a)), typeof rep == "function" && (i = rep.call(b, a, i));
        switch (typeof i) {
        case "string":
            return quote(i);
        case "number":
            return isFinite(i) ? String(i) : "null";
        case "boolean":
        case "null":
            return String(i);
        case "object":
            if (!i) return "null";
            gap += indent, h = [];
            if (Object.prototype.toString.apply(i) === "[object Array]") {
                f = i.length;
                for (c = 0; c < f; c += 1) h[c] = str(c, i) || "null";
                e = h.length === 0 ? "[]" : gap ? "[\n" + gap + h.join(",\n" + gap) + "\n" + g + "]" : "[" + h.join(",") + "]", gap = g;
                return e
            }
            if (rep && typeof rep == "object") {
                f = rep.length;
                for (c = 0; c < f; c += 1) typeof rep[c] == "string" && (d = rep[c], e = str(d, i), e && h.push(quote(d) + (gap ? ": " : ":") + e))
            } else for (d in i) Object.prototype.hasOwnProperty.call(i, d) && (e = str(d, i), e && h.push(quote(d) + (gap ? ": " : ":") + e));
            e = h.length === 0 ? "{}" : gap ? "{\n" + gap + h.join(",\n" + gap) + "\n" + g + "}" : "{" + h.join(",") + "}", gap = g;
            return e
        }
    }
    function quote(a) {
        escapable.lastIndex = 0;
        return escapable.test(a) ? ‘"‘ + a.replace(escapable, function(a) {
            var b = meta[a];
            return typeof b == "string" ? b : "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4)
        }) + ‘"‘ : ‘"‘ + a + ‘"‘
    }
    function f(a) {
        return a < 10 ? "0" + a : a
    }
    "use strict", typeof Date.prototype.toJSON != "function" && (Date.prototype.toJSON = function(a) {
        return isFinite(this.valueOf()) ? this.getUTCFullYear() + "-" + f(this.getUTCMonth() + 1) + "-" + f(this.getUTCDate()) + "T" + f(this.getUTCHours()) + ":" + f(this.getUTCMinutes()) + ":" + f(this.getUTCSeconds()) + "Z" : null
    }, String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function(a) {
        return this.valueOf()
    });
    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap, indent, meta = {
            "\b": "\\b",
            "\t": "\\t",
            "\n": "\\n",
            "\f": "\\f",
            "\r": "\\r",
            ‘"‘: ‘\\"‘,
            "\\": "\\\\"
        },
        rep;
    typeof JSON.stringify != "function" && (JSON.stringify = function(a, b, c) {
        var d;
        gap = "", indent = "";
        if (typeof c == "number") for (d = 0; d < c; d += 1) indent += " ";
        else typeof c == "string" && (indent = c);
        rep = b;
        if (!b || typeof b == "function" || typeof b == "object" && typeof b.length == "number") return str("", {
            "": a
        });
        throw new Error("JSON.stringify")
    }), typeof JSON.parse != "function" && (JSON.parse = function(text, reviver) {
        function walk(a, b) {
            var c, d, e = a[b];
            if (e && typeof e == "object") for (c in e) Object.prototype.hasOwnProperty.call(e, c) && (d = walk(e, c), d !== undefined ? e[c] = d : delete e[c]);
            return reviver.call(a, b, e)
        }
        var j;
        text = String(text), cx.lastIndex = 0, cx.test(text) && (text = text.replace(cx, function(a) {
            return "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4)
        }));
        if (/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]").replace(/(?:^|:|,)(?:\s*\[)+/g, ""))) {
            j = eval("(" + text + ")");
            return typeof reviver == "function" ? walk({
                "": j
            }, "") : j
        }
        throw new SyntaxError("JSON.parse")
    })
}()

SockJS = function() {
    var a = document,
        b = window,
        c = {},
        d = function() {};
    d.prototype.addEventListener = function(a, b) {
        this._listeners || (this._listeners = {}), a in this._listeners || (this._listeners[a] = []);
        var d = this._listeners[a];
        c.arrIndexOf(d, b) === -1 && d.push(b);
        return
    }, d.prototype.removeEventListener = function(a, b) {
        if (!(this._listeners && a in this._listeners)) return;
        var d = this._listeners[a],
            e = c.arrIndexOf(d, b);
        if (e !== -1) {
            d.length > 1 ? this._listeners[a] = d.slice(0, e).concat(d.slice(e + 1)) : delete this._listeners[a];
            return
        }
        return
    }, d.prototype.dispatchEvent = function(a) {
        var b = a.type,
            c = Array.prototype.slice.call(arguments, 0);
        this["on" + b] && this["on" + b].apply(this, c);
        if (this._listeners && b in this._listeners) for (var d = 0; d < this._listeners[b].length; d++) this._listeners[b][d].apply(this, c)
    };
    var e = function(a, b) {
            this.type = a;
            if (typeof b != "undefined") for (var c in b) {
                if (!b.hasOwnProperty(c)) continue;
                this[c] = b[c]
            }
        };
    e.prototype.toString = function() {
        var a = [];
        for (var b in this) {
            if (!this.hasOwnProperty(b)) continue;
            var c = this[b];
            typeof c == "function" && (c = "[function]"), a.push(b + "=" + c)
        }
        return "SimpleEvent(" + a.join(", ") + ")"
    };
    var f = function(a) {
            var b = this;
            b._events = a || [], b._listeners = {}
        };
    f.prototype.emit = function(a) {
        var b = this;
        b._verifyType(a);
        if (b._nuked) return;
        var c = Array.prototype.slice.call(arguments, 1);
        b["on" + a] && b["on" + a].apply(b, c);
        if (a in b._listeners) for (var d = 0; d < b._listeners[a].length; d++) b._listeners[a][d].apply(b, c)
    }, f.prototype.on = function(a, b) {
        var c = this;
        c._verifyType(a);
        if (c._nuked) return;
        a in c._listeners || (c._listeners[a] = []), c._listeners[a].push(b)
    }, f.prototype._verifyType = function(a) {
        var b = this;
        c.arrIndexOf(b._events, a) === -1 && c.log("Event " + JSON.stringify(a) + " not listed " + JSON.stringify(b._events) + " in " + b)
    }, f.prototype.nuke = function() {
        var a = this;
        a._nuked = !0;
        for (var b = 0; b < a._events.length; b++) delete a[a._events[b]];
        a._listeners = {}
    };
    var g = "abcdefghijklmnopqrstuvwxyz0123456789_";
    c.random_string = function(a, b) {
        b = b || g.length;
        var c, d = [];
        for (c = 0; c < a; c++) d.push(g.substr(Math.floor(Math.random() * b), 1));
        return d.join("")
    }, c.random_number = function(a) {
        return Math.floor(Math.random() * a)
    }, c.random_number_string = function(a) {
        var b = ("" + (a - 1)).length,
            d = Array(b + 1).join("0");
        return (d + c.random_number(a)).slice(-b)
    }, c.getOrigin = function(a) {
        a += "/";
        var b = a.split("/").slice(0, 3);
        return b.join("/")
    }, c.isSameOriginUrl = function(a, c) {
        return c || (c = b.location.href), a.split("/").slice(0, 3).join("/") === c.split("/").slice(0, 3).join("/")
    }, c.getParentDomain = function(a) {
        if (/^[0-9.]*$/.test(a)) return a;
        if (/^\[/.test(a)) return a;
        if (!/[.]/.test(a)) return a;
        var b = a.split(".").slice(1);
        return b.join(".")
    }, c.objectExtend = function(a, b) {
        for (var c in b) b.hasOwnProperty(c) && (a[c] = b[c]);
        return a
    };
    var h = "_jp";
    c.polluteGlobalNamespace = function() {
        h in b || (b[h] = {})
    }, c.closeFrame = function(a, b) {
        return "c" + JSON.stringify([a, b])
    }, c.userSetCode = function(a) {
        return a === 1e3 || a >= 3e3 && a <= 4999
    }, c.countRTO = function(a) {
        var b;
        return a > 100 ? b = 3 * a : b = a + 200, b
    }, c.log = function() {
        b.console && console.log && console.log.apply && console.log.apply(console, arguments)
    }, c.bind = function(a, b) {
        return a.bind ? a.bind(b) : function() {
            return a.apply(b, arguments)
        }
    }, c.flatUrl = function(a) {
        return a.indexOf("?") === -1 && a.indexOf("#") === -1
    }, c.amendUrl = function(b) {
        var d = a.location;
        if (!b) throw new Error("Wrong url for SockJS");
        if (!c.flatUrl(b)) throw new Error("Only basic urls are supported in SockJS");
        return b.indexOf("//") === 0 && (b = d.protocol + b), b.indexOf("/") === 0 && (b = d.protocol + "//" + d.host + b), b = b.replace(/[/]+$/, ""), b
    }, c.arrIndexOf = function(a, b) {
        for (var c = 0; c < a.length; c++) if (a[c] === b) return c;
        return -1
    }, c.arrSkip = function(a, b) {
        var d = c.arrIndexOf(a, b);
        if (d === -1) return a.slice();
        var e = a.slice(0, d);
        return e.concat(a.slice(d + 1))
    }, c.isArray = Array.isArray ||
    function(a) {
        return {}.toString.call(a).indexOf("Array") >= 0
    }, c.delay = function(a, b) {
        return typeof a == "function" && (b = a, a = 0), setTimeout(b, a)
    };
    var i = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        j = {
            "\0": "\\u0000",
            "\x01": "\\u0001",
            "\x02": "\\u0002",
            "\x03": "\\u0003",
            "\x04": "\\u0004",
            "\x05": "\\u0005",
            "\x06": "\\u0006",
            "\x07": "\\u0007",
            "\b": "\\b",
            "\t": "\\t",
            "\n": "\\n",
            "\x0b": "\\u000b",
            "\f": "\\f",
            "\r": "\\r",
            "\x0e": "\\u000e",
            "\x0f": "\\u000f",
            "\x10": "\\u0010",
            "\x11": "\\u0011",
            "\x12": "\\u0012",
            "\x13": "\\u0013",
            "\x14": "\\u0014",
            "\x15": "\\u0015",
            "\x16": "\\u0016",
            "\x17": "\\u0017",
            "\x18": "\\u0018",
            "\x19": "\\u0019",
            "\x1a": "\\u001a",
            "\x1b": "\\u001b",
            "\x1c": "\\u001c",
            "\x1d": "\\u001d",
            "\x1e": "\\u001e",
            "\x1f": "\\u001f",
            ‘"‘: ‘\\"‘,
            "\\": "\\\\",
            "\x7f": "\\u007f",
            "\x80": "\\u0080",
            "\x81": "\\u0081",
            "\x82": "\\u0082",
            "\x83": "\\u0083",
            "\x84": "\\u0084",
            "\x85": "\\u0085",
            "\x86": "\\u0086",
            "\x87": "\\u0087",
            "\x88": "\\u0088",
            "\x89": "\\u0089",
            "\x8a": "\\u008a",
            "\x8b": "\\u008b",
            "\x8c": "\\u008c",
            "\x8d": "\\u008d",
            "\x8e": "\\u008e",
            "\x8f": "\\u008f",
            "\x90": "\\u0090",
            "\x91": "\\u0091",
            "\x92": "\\u0092",
            "\x93": "\\u0093",
            "\x94": "\\u0094",
            "\x95": "\\u0095",
            "\x96": "\\u0096",
            "\x97": "\\u0097",
            "\x98": "\\u0098",
            "\x99": "\\u0099",
            "\x9a": "\\u009a",
            "\x9b": "\\u009b",
            "\x9c": "\\u009c",
            "\x9d": "\\u009d",
            "\x9e": "\\u009e",
            "\x9f": "\\u009f",
            "\xad": "\\u00ad",
            "\u0600": "\\u0600",
            "\u0601": "\\u0601",
            "\u0602": "\\u0602",
            "\u0603": "\\u0603",
            "\u0604": "\\u0604",
            "\u070f": "\\u070f",
            "\u17b4": "\\u17b4",
            "\u17b5": "\\u17b5",
            "\u200c": "\\u200c",
            "\u200d": "\\u200d",
            "\u200e": "\\u200e",
            "\u200f": "\\u200f",
            "\u2028": "\\u2028",
            "\u2029": "\\u2029",
            "\u202a": "\\u202a",
            "\u202b": "\\u202b",
            "\u202c": "\\u202c",
            "\u202d": "\\u202d",
            "\u202e": "\\u202e",
            "\u202f": "\\u202f",
            "\u2060": "\\u2060",
            "\u2061": "\\u2061",
            "\u2062": "\\u2062",
            "\u2063": "\\u2063",
            "\u2064": "\\u2064",
            "\u2065": "\\u2065",
            "\u2066": "\\u2066",
            "\u2067": "\\u2067",
            "\u2068": "\\u2068",
            "\u2069": "\\u2069",
            "\u206a": "\\u206a",
            "\u206b": "\\u206b",
            "\u206c": "\\u206c",
            "\u206d": "\\u206d",
            "\u206e": "\\u206e",
            "\u206f": "\\u206f",
            "\ufeff": "\\ufeff",
            "\ufff0": "\\ufff0",
            "\ufff1": "\\ufff1",
            "\ufff2": "\\ufff2",
            "\ufff3": "\\ufff3",
            "\ufff4": "\\ufff4",
            "\ufff5": "\\ufff5",
            "\ufff6": "\\ufff6",
            "\ufff7": "\\ufff7",
            "\ufff8": "\\ufff8",
            "\ufff9": "\\ufff9",
            "\ufffa": "\\ufffa",
            "\ufffb": "\\ufffb",
            "\ufffc": "\\ufffc",
            "\ufffd": "\\ufffd",
            "\ufffe": "\\ufffe",
            "\uffff": "\\uffff"
        },
        k = /[\x00-\x1f\ud800-\udfff\ufffe\uffff\u0300-\u0333\u033d-\u0346\u034a-\u034c\u0350-\u0352\u0357-\u0358\u035c-\u0362\u0374\u037e\u0387\u0591-\u05af\u05c4\u0610-\u0617\u0653-\u0654\u0657-\u065b\u065d-\u065e\u06df-\u06e2\u06eb-\u06ec\u0730\u0732-\u0733\u0735-\u0736\u073a\u073d\u073f-\u0741\u0743\u0745\u0747\u07eb-\u07f1\u0951\u0958-\u095f\u09dc-\u09dd\u09df\u0a33\u0a36\u0a59-\u0a5b\u0a5e\u0b5c-\u0b5d\u0e38-\u0e39\u0f43\u0f4d\u0f52\u0f57\u0f5c\u0f69\u0f72-\u0f76\u0f78\u0f80-\u0f83\u0f93\u0f9d\u0fa2\u0fa7\u0fac\u0fb9\u1939-\u193a\u1a17\u1b6b\u1cda-\u1cdb\u1dc0-\u1dcf\u1dfc\u1dfe\u1f71\u1f73\u1f75\u1f77\u1f79\u1f7b\u1f7d\u1fbb\u1fbe\u1fc9\u1fcb\u1fd3\u1fdb\u1fe3\u1feb\u1fee-\u1fef\u1ff9\u1ffb\u1ffd\u2000-\u2001\u20d0-\u20d1\u20d4-\u20d7\u20e7-\u20e9\u2126\u212a-\u212b\u2329-\u232a\u2adc\u302b-\u302c\uaab2-\uaab3\uf900-\ufa0d\ufa10\ufa12\ufa15-\ufa1e\ufa20\ufa22\ufa25-\ufa26\ufa2a-\ufa2d\ufa30-\ufa6d\ufa70-\ufad9\ufb1d\ufb1f\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40-\ufb41\ufb43-\ufb44\ufb46-\ufb4e\ufff0-\uffff]/g,
        l, m = JSON && JSON.stringify ||
    function(a) {
        return i.lastIndex = 0, i.test(a) && (a = a.replace(i, function(a) {
            return j[a]
        })), ‘"‘ + a + ‘"‘
    }, n = function(a) {
        var b, c = {},
            d = [];
        for (b = 0; b < 65536; b++) d.push(String.fromCharCode(b));
        return a.lastIndex = 0, d.join("").replace(a, function(a) {
            return c[a] = "\\u" + ("0000" + a.charCodeAt(0).toString(16)).slice(-4), ""
        }), a.lastIndex = 0, c
    };
    c.quote = function(a) {
        var b = m(a);
        return k.lastIndex = 0, k.test(b) ? (l || (l = n(k)), b.replace(k, function(a) {
            return l[a]
        })) : b
    };
    var o = ["websocket", "xdr-streaming", "xhr-streaming", "iframe-eventsource", "iframe-htmlfile", "xdr-polling", "xhr-polling", "iframe-xhr-polling", "jsonp-polling"];
    c.probeProtocols = function() {
        var a = {};
        for (var b = 0; b < o.length; b++) {
            var c = o[b];
            a[c] = y[c] && y[c].enabled()
        }
        return a
    }, c.detectProtocols = function(a, b, c) {
        var d = {},
            e = [];
        b || (b = o);
        for (var f = 0; f < b.length; f++) {
            var g = b[f];
            d[g] = a[g]
        }
        var h = function(a) {
                var b = a.shift();
                d[b] ? e.push(b) : a.length > 0 && h(a)
            };
        return c.websocket !== !1 && h(["websocket"]), d["xhr-streaming"] && !c.null_origin ? e.push("xhr-streaming") : d["xdr-streaming"] && !c.cookie_needed && !c.null_origin ? e.push("xdr-streaming") : h(["iframe-eventsource", "iframe-htmlfile"]), d["xhr-polling"] && !c.null_origin ? e.push("xhr-polling") : d["xdr-polling"] && !c.cookie_needed && !c.null_origin ? e.push("xdr-polling") : h(["iframe-xhr-polling", "jsonp-polling"]), e
    };
    var p = "_sockjs_global";
    c.createHook = function() {
        var a = "a" + c.random_string(8);
        if (!(p in b)) {
            var d = {};
            b[p] = function(a) {
                return a in d || (d[a] = {
                    id: a,
                    del: function() {
                        delete d[a]
                    }
                }), d[a]
            }
        }
        return b[p](a)
    }, c.attachMessage = function(a) {
        c.attachEvent("message", a)
    }, c.attachEvent = function(c, d) {
        typeof b.addEventListener != "undefined" ? b.addEventListener(c, d, !1) : (a.attachEvent("on" + c, d), b.attachEvent("on" + c, d))
    }, c.detachMessage = function(a) {
        c.detachEvent("message", a)
    }, c.detachEvent = function(c, d) {
        typeof b.addEventListener != "undefined" ? b.removeEventListener(c, d, !1) : (a.detachEvent("on" + c, d), b.detachEvent("on" + c, d))
    };
    var q = {},
        r = !1,
        s = function() {
            for (var a in q) q[a](), delete q[a]
        },
        t = function() {
            if (r) return;
            r = !0, s()
        };
    c.attachEvent("unload", t), c.unload_add = function(a) {
        var b = c.random_string(8);
        return q[b] = a, r && c.delay(s), b
    }, c.unload_del = function(a) {
        a in q && delete q[a]
    }, c.createIframe = function(b, d) {
        var e = a.createElement("iframe"),
            f, g, h = function() {
                clearTimeout(f);
                try {
                    e.onload = null
                } catch (a) {}
                e.onerror = null
            },
            i = function() {
                e && (h(), setTimeout(function() {
                    e && e.parentNode.removeChild(e), e = null
                }, 0), c.unload_del(g))
            },
            j = function(a) {
                e && (i(), d(a))
            },
            k = function(a, b) {
                try {
                    e && e.contentWindow && e.contentWindow.postMessage(a, b)
                } catch (c) {}
            };
        return e.src = b, e.style.display = "none", e.style.position = "absolute", e.onerror = function() {
            j("onerror")
        }, e.onload = function() {
            clearTimeout(f), f = setTimeout(function() {
                j("onload timeout")
            }, 2e3)
        }, a.body.appendChild(e), f = setTimeout(function() {
            j("timeout")
        }, 15e3), g = c.unload_add(i), {
            post: k,
            cleanup: i,
            loaded: h
        }
    }, c.createHtmlfile = function(a, d) {
        var e = new ActiveXObject("htmlfile"),
            f, g, i, j = function() {
                clearTimeout(f)
            },
            k = function() {
                e && (j(), c.unload_del(g), i.parentNode.removeChild(i), i = e = null, CollectGarbage())
            },
            l = function(a) {
                e && (k(), d(a))
            },
            m = function(a, b) {
                try {
                    i && i.contentWindow && i.contentWindow.postMessage(a, b)
                } catch (c) {}
            };
        e.open(), e.write(‘<html><script>document.domain="‘ + document.domain + ‘";‘ + "</s" + "cript></html>"), e.close(), e.parentWindow[h] = b[h];
        var n = e.createElement("div");
        return e.body.appendChild(n), i = e.createElement("iframe"), n.appendChild(i), i.src = a, f = setTimeout(function() {
            l("timeout")
        }, 15e3), g = c.unload_add(k), {
            post: m,
            cleanup: k,
            loaded: j
        }
    };
    var u = function() {};
    u.prototype = new f(["chunk", "finish"]), u.prototype._start = function(a, d, e, f) {
        var g = this;
        try {
            g.xhr = new XMLHttpRequest
        } catch (h) {}
        if (!g.xhr) try {
            g.xhr = new b.ActiveXObject("Microsoft.XMLHTTP")
        } catch (h) {}
        if (b.ActiveXObject || b.XDomainRequest) d += (d.indexOf("?") === -1 ? "?" : "&") + "t=" + +(new Date);
        g.unload_ref = c.unload_add(function() {
            g._cleanup(!0)
        });
        try {
            g.xhr.open(a, d, !0)
        } catch (i) {
            g.emit("finish", 0, ""), g._cleanup();
            return
        }
        if (!f || !f.no_credentials) g.xhr.withCredentials = "true";
        if (f && f.headers) for (var j in f.headers) g.xhr.setRequestHeader(j, f.headers[j]);
        g.xhr.onreadystatechange = function() {
            if (g.xhr) {
                var a = g.xhr;
                switch (a.readyState) {
                case 3:
                    try {
                        var b = a.status,
                            c = a.responseText
                    } catch (a) {}
                    b === 1223 && (b = 204), c && c.length > 0 && g.emit("chunk", b, c);
                    break;
                case 4:
                    var b = a.status;
                    b === 1223 && (b = 204), g.emit("finish", b, a.responseText), g._cleanup(!1)
                }
            }
        }, g.xhr.send(e)
    }, u.prototype._cleanup = function(a) {
        var b = this;
        if (!b.xhr) return;
        c.unload_del(b.unload_ref), b.xhr.onreadystatechange = function() {};
        if (a) try {
            b.xhr.abort()
        } catch (d) {}
        b.unload_ref = b.xhr = null
    }, u.prototype.close = function() {
        var a = this;
        a.nuke(), a._cleanup(!0)
    };
    var v = c.XHRCorsObject = function() {
            var a = this,
                b = arguments;
            c.delay(function() {
                a._start.apply(a, b)
            })
        };
    v.prototype = new u;
    var w = c.XHRLocalObject = function(a, b, d) {
            var e = this;
            c.delay(function() {
                e._start(a, b, d, {
                    no_credentials: !0
                })
            })
        };
    w.prototype = new u;
    var x = c.XDRObject = function(a, b, d) {
            var e = this;
            c.delay(function() {
                e._start(a, b, d)
            })
        };
    x.prototype = new f(["chunk", "finish"]), x.prototype._start = function(a, b, d) {
        var e = this,
            f = new XDomainRequest;
        b += (b.indexOf("?") === -1 ? "?" : "&") + "t=" + +(new Date);
        var g = f.ontimeout = f.onerror = function() {
                e.emit("finish", 0, ""), e._cleanup(!1)
            };
        f.onprogress = function() {
            e.emit("chunk", 200, f.responseText)
        }, f.onload = function() {
            e.emit("finish", 200, f.responseText), e._cleanup(!1)
        }, e.xdr = f, e.unload_ref = c.unload_add(function() {
            e._cleanup(!0)
        });
        try {
            e.xdr.open(a, b), e.xdr.send(d)
        } catch (h) {
            g()
        }
    }, x.prototype._cleanup = function(a) {
        var b = this;
        if (!b.xdr) return;
        c.unload_del(b.unload_ref), b.xdr.ontimeout = b.xdr.onerror = b.xdr.onprogress = b.xdr.onload = null;
        if (a) try {
            b.xdr.abort()
        } catch (d) {}
        b.unload_ref = b.xdr = null
    }, x.prototype.close = function() {
        var a = this;
        a.nuke(), a._cleanup(!0)
    }, c.isXHRCorsCapable = function() {
        return b.XMLHttpRequest && "withCredentials" in new XMLHttpRequest ? 1 : b.XDomainRequest && a.domain ? 2 : L.enabled() ? 3 : 4
    };
    var y = function(a, d, e) {
            if (this === b) return new y(a, d, e);
            var f = this,
                g;
            f._options = {
                devel: !1,
                debug: !1,
                protocols_whitelist: [],
                info: undefined,
                rtt: undefined
            }, e && c.objectExtend(f._options, e), f._base_url = c.amendUrl(a), f._server = f._options.server || c.random_number_string(1e3), f._options.protocols_whitelist && f._options.protocols_whitelist.length ? g = f._options.protocols_whitelist : (typeof d == "string" && d.length > 0 ? g = [d] : c.isArray(d) ? g = d : g = null, g && f._debug(‘Deprecated API: Use "protocols_whitelist" option instead of supplying protocol list as a second parameter to SockJS constructor.‘)), f._protocols = [], f.protocol = null, f.readyState = y.CONNECTING, f._ir = S(f._base_url), f._ir.onfinish = function(a, b) {
                f._ir = null, a ? (f._options.info && (a = c.objectExtend(a, f._options.info)), f._options.rtt && (b = f._options.rtt), f._applyInfo(a, b, g), f._didClose()) : f._didClose(1002, "Can‘t connect to server", !0)
            }
        };
    y.prototype = new d, y.version = "0.3.4", y.CONNECTING = 0, y.OPEN = 1, y.CLOSING = 2, y.CLOSED = 3, y.prototype._debug = function() {
        this._options.debug && c.log.apply(c, arguments)
    }, y.prototype._dispatchOpen = function() {
        var a = this;
        a.readyState === y.CONNECTING ? (a._transport_tref && (clearTimeout(a._transport_tref), a._transport_tref = null), a.readyState = y.OPEN, a.dispatchEvent(new e("open"))) : a._didClose(1006, "Server lost session")
    }, y.prototype._dispatchMessage = function(a) {
        var b = this;
        if (b.readyState !== y.OPEN) return;
        b.dispatchEvent(new e("message", {
            data: a
        }))
    }, y.prototype._dispatchHeartbeat = function(a) {
        var b = this;
        if (b.readyState !== y.OPEN) return;
        b.dispatchEvent(new e("heartbeat", {}))
    }, y.prototype._didClose = function(a, b, d) {
        var f = this;
        if (f.readyState !== y.CONNECTING && f.readyState !== y.OPEN && f.readyState !== y.CLOSING) throw new Error("INVALID_STATE_ERR");
        f._ir && (f._ir.nuke(), f._ir = null), f._transport && (f._transport.doCleanup(), f._transport = null);
        var g = new e("close", {
            code: a,
            reason: b,
            wasClean: c.userSetCode(a)
        });
        if (!c.userSetCode(a) && f.readyState === y.CONNECTING && !d) {
            if (f._try_next_protocol(g)) return;
            g = new e("close", {
                code: 2e3,
                reason: "All transports failed",
                wasClean: !1,
                last_event: g
            })
        }
        f.readyState = y.CLOSED, c.delay(function() {
            f.dispatchEvent(g)
        })
    }, y.prototype._didMessage = function(a) {
        var b = this,
            c = a.slice(0, 1);
        switch (c) {
        case "o":
            b._dispatchOpen();
            break;
        case "a":
            var d = JSON.parse(a.slice(1) || "[]");
            for (var e = 0; e < d.length; e++) b._dispatchMessage(d[e]);
            break;
        case "m":
            var d = JSON.parse(a.slice(1) || "null");
            b._dispatchMessage(d);
            break;
        case "c":
            var d = JSON.parse(a.slice(1) || "[]");
            b._didClose(d[0], d[1]);
            break;
        case "h":
            b._dispatchHeartbeat()
        }
    }, y.prototype._try_next_protocol = function(b) {
        var d = this;
        d.protocol && (d._debug("Closed transport:", d.protocol, "" + b), d.protocol = null), d._transport_tref && (clearTimeout(d._transport_tref), d._transport_tref = null);
        for (;;) {
            var e = d.protocol = d._protocols.shift();
            if (!e) return !1;
            if (y[e] && y[e].need_body === !0 && (!a.body || typeof a.readyState != "undefined" && a.readyState !== "complete")) return d._protocols.unshift(e), d.protocol = "waiting-for-load", c.attachEvent("load", function() {
                d._try_next_protocol()
            }), !0;
            if ( !! y[e] && !! y[e].enabled(d._options)) {
                var f = y[e].roundTrips || 1,
                    g = (d._options.rto || 0) * f || 5e3;
                d._transport_tref = c.delay(g, function() {
                    d.readyState === y.CONNECTING && d._didClose(2007, "Transport timeouted")
                });
                var h = c.random_string(8),
                    i = d._base_url + "/" + d._server + "/" + h;
                return d._debug("Opening transport:", e, " url:" + i, " RTO:" + d._options.rto), d._transport = new y[e](d, i, d._base_url), !0
            }
            d._debug("Skipping transport:", e)
        }
    }, y.prototype.close = function(a, b) {
        var d = this;
        if (a && !c.userSetCode(a)) throw new Error("INVALID_ACCESS_ERR");
        return d.readyState !== y.CONNECTING && d.readyState !== y.OPEN ? !1 : (d.readyState = y.CLOSING, d._didClose(a || 1e3, b || "Normal closure"), !0)
    }, y.prototype.send = function(a) {
        var b = this;
        if (b.readyState === y.CONNECTING) throw new Error("INVALID_STATE_ERR");
        return b.readyState === y.OPEN && b._transport.doSend(c.quote("" + a)), !0
    }, y.prototype._applyInfo = function(b, d, e) {
        var f = this;
        f._options.info = b, f._options.rtt = d, f._options.rto = c.countRTO(d), f._options.info.null_origin = !a.domain;
        var g = c.probeProtocols();
        f._protocols = c.detectProtocols(g, e, b)
    };
    var z = y.websocket = function(a, d) {
            var e = this,
                f = d + "/websocket";
            f.slice(0, 5) === "https" ? f = "wss" + f.slice(5) : f = "ws" + f.slice(4), e.ri = a, e.url = f;
            var g = b.WebSocket || b.MozWebSocket;
            e.ws = new g(e.url), e.ws.onmessage = function(a) {
                e.ri._didMessage(a.data)
            }, e.unload_ref = c.unload_add(function() {
                e.ws.close()
            }), e.ws.onclose = function() {
                e.ri._didMessage(c.closeFrame(1006, "WebSocket connection broken"))
            }
        };
    z.prototype.doSend = function(a) {
        this.ws.send("[" + a + "]")
    }, z.prototype.doCleanup = function() {
        var a = this,
            b = a.ws;
        b && (b.onmessage = b.onclose = null, b.close(), c.unload_del(a.unload_ref), a.unload_ref = a.ri = a.ws = null)
    }, z.enabled = function() {
        return !!b.WebSocket || !! b.MozWebSocket
    }, z.roundTrips = 2;
    var A = function() {};
    A.prototype.send_constructor = function(a) {
        var b = this;
        b.send_buffer = [], b.sender = a
    }, A.prototype.doSend = function(a) {
        var b = this;
        b.send_buffer.push(a), b.send_stop || b.send_schedule()
    }, A.prototype.send_schedule_wait = function() {
        var a = this,
            b;
        a.send_stop = function() {
            a.send_stop = null, clearTimeout(b)
        }, b = c.delay(25, function() {
            a.send_stop = null, a.send_schedule()
        })
    }, A.prototype.send_schedule = function() {
        var a = this;
        if (a.send_buffer.length > 0) {
            var b = "[" + a.send_buffer.join(",") + "]";
            a.send_stop = a.sender(a.trans_url, b, function(b, c) {
                a.send_stop = null, b === !1 ? a.ri._didClose(1006, "Sending error " + c) : a.send_schedule_wait()
            }), a.send_buffer = []
        }
    }, A.prototype.send_destructor = function() {
        var a = this;
        a._send_stop && a._send_stop(), a._send_stop = null
    };
    var B = function(b, d, e) {
            var f = this;
            if (!("_send_form" in f)) {
                var g = f._send_form = a.createElement("form"),
                    h = f._send_area = a.createElement("textarea");
                h.name = "d", g.style.display = "none", g.style.position = "absolute", g.method = "POST", g.enctype = "application/x-www-form-urlencoded", g.acceptCharset = "UTF-8", g.appendChild(h), a.body.appendChild(g)
            }
            var g = f._send_form,
                h = f._send_area,
                i = "a" + c.random_string(8);
            g.target = i, g.action = b + "/jsonp_send?i=" + i;
            var j;
            try {
                j = a.createElement(‘<iframe name="‘ + i + ‘">‘)
            } catch (k) {
                j = a.createElement("iframe"), j.name = i
            }
            j.id = i, g.appendChild(j), j.style.display = "none";
            try {
                h.value = d
            } catch (l) {
                c.log("Your browser is seriously broken. Go home! " + l.message)
            }
            g.submit();
            var m = function(a) {
                    if (!j.onerror) return;
                    j.onreadystatechange = j.onerror = j.onload = null, c.delay(500, function() {
                        j.parentNode.removeChild(j), j = null
                    }), h.value = "", e(!0)
                };
            return j.onerror = j.onload = m, j.onreadystatechange = function(a) {
                j.readyState == "complete" && m()
            }, m
        },
        C = function(a) {
            return function(b, c, d) {
                var e = new a("POST", b + "/xhr_send", c);
                return e.onfinish = function(a, b) {
                    d(a === 200 || a === 204, "http status " + a)
                }, function(a) {
                    d(!1, a)
                }
            }
        },
        D = function(b, d) {
            var e, f = a.createElement("script"),
                g, h = function(a) {
                    g && (g.parentNode.removeChild(g), g = null), f && (clearTimeout(e), f.parentNode.removeChild(f), f.onreadystatechange = f.onerror = f.onload = f.onclick = null, f = null, d(a), d = null)
                },
                i = !1,
                j = null;
            f.id = "a" + c.random_string(8), f.src = b, f.type = "text/javascript", f.charset = "UTF-8", f.onerror = function(a) {
                j || (j = setTimeout(function() {
                    i || h(c.closeFrame(1006, "JSONP script loaded abnormally (onerror)"))
                }, 1e3))
            }, f.onload = function(a) {
                h(c.closeFrame(1006, "JSONP script loaded abnormally (onload)"))
            }, f.onreadystatechange = function(a) {
                if (/loaded|closed/.test(f.readyState)) {
                    if (f && f.htmlFor && f.onclick) {
                        i = !0;
                        try {
                            f.onclick()
                        } catch (b) {}
                    }
                    f && h(c.closeFrame(1006, "JSONP script loaded abnormally (onreadystatechange)"))
                }
            };
            if (typeof f.async == "undefined" && a.attachEvent) if (!/opera/i.test(navigator.userAgent)) {
                try {
                    f.htmlFor = f.id, f.event = "onclick"
                } catch (k) {}
                f.async = !0
            } else g = a.createElement("script"), g.text = "try{var a = document.getElementById(‘" + f.id + "‘); if(a)a.onerror();}catch(x){};", f.async = g.async = !1;
            typeof f.async != "undefined" && (f.async = !0), e = setTimeout(function() {
                h(c.closeFrame(1006, "JSONP script loaded abnormally (timeout)"))
            }, 35e3);
            var l = a.getElementsByTagName("head")[0];
            return l.insertBefore(f, l.firstChild), g && l.insertBefore(g, l.firstChild), h
        },
        E = y["jsonp-polling"] = function(a, b) {
            c.polluteGlobalNamespace();
            var d = this;
            d.ri = a, d.trans_url = b, d.send_constructor(B), d._schedule_recv()
        };
    E.prototype = new A, E.prototype._schedule_recv = function() {
        var a = this,
            b = function(b) {
                a._recv_stop = null, b && (a._is_closing || a.ri._didMessage(b)), a._is_closing || a._schedule_recv()
            };
        a._recv_stop = F(a.trans_url + "/jsonp", D, b)
    }, E.enabled = function() {
        return !0
    }, E.need_body = !0, E.prototype.doCleanup = function() {
        var a = this;
        a._is_closing = !0, a._recv_stop && a._recv_stop(), a.ri = a._recv_stop = null, a.send_destructor()
    };
    var F = function(a, d, e) {
            var f = "a" + c.random_string(6),
                g = a + "?c=" + escape(h + "." + f),
                i = 0,
                j = function(a) {
                    switch (i) {
                    case 0:
                        delete b[h][f], e(a);
                        break;
                    case 1:
                        e(a), i = 2;
                        break;
                    case 2:
                        delete b[h][f]
                    }
                },
                k = d(g, j);
            b[h][f] = k;
            var l = function() {
                    b[h][f] && (i = 1, b[h][f](c.closeFrame(1e3, "JSONP user aborted read")))
                };
            return l
        },
        G = function() {};
    G.prototype = new A, G.prototype.run = function(a, b, c, d, e) {
        var f = this;
        f.ri = a, f.trans_url = b, f.send_constructor(C(e)), f.poll = new $(a, d, b + c, e)
    }, G.prototype.doCleanup = function() {
        var a = this;
        a.poll && (a.poll.abort(), a.poll = null)
    };
    var H = y["xhr-streaming"] = function(a, b) {
            this.run(a, b, "/xhr_streaming", bd, c.XHRCorsObject)
        };
    H.prototype = new G, H.enabled = function() {
        return b.XMLHttpRequest && "withCredentials" in new XMLHttpRequest && !/opera/i.test(navigator.userAgent)
    }, H.roundTrips = 2, H.need_body = !0;
    var I = y["xdr-streaming"] = function(a, b) {
            this.run(a, b, "/xhr_streaming", bd, c.XDRObject)
        };
    I.prototype = new G, I.enabled = function() {
        return !!b.XDomainRequest
    }, I.roundTrips = 2;
    var J = y["xhr-polling"] = function(a, b) {
            this.run(a, b, "/xhr", bd, c.XHRCorsObject)
        };
    J.prototype = new G, J.enabled = H.enabled, J.roundTrips = 2;
    var K = y["xdr-polling"] = function(a, b) {
            this.run(a, b, "/xhr", bd, c.XDRObject)
        };
    K.prototype = new G, K.enabled = I.enabled, K.roundTrips = 2;
    var L = function() {};
    L.prototype.i_constructor = function(a, b, d) {
        var e = this;
        e.ri = a, e.origin = c.getOrigin(d), e.base_url = d, e.trans_url = b;
        var f = d + "/iframe.html";
        e.ri._options.devel && (f += "?t=" + +(new Date)), e.window_id = c.random_string(8), f += "#" + e.window_id, e.iframeObj = c.createIframe(f, function(a) {
            e.ri._didClose(1006, "Unable to load an iframe (" + a + ")")
        }), e.onmessage_cb = c.bind(e.onmessage, e), c.attachMessage(e.onmessage_cb)
    }, L.prototype.doCleanup = function() {
        var a = this;
        if (a.iframeObj) {
            c.detachMessage(a.onmessage_cb);
            try {
                a.iframeObj.iframe.contentWindow && a.postMessage("c")
            } catch (b) {}
            a.iframeObj.cleanup(), a.iframeObj = null, a.onmessage_cb = a.iframeObj = null
        }
    }, L.prototype.onmessage = function(a) {
        var b = this;
        if (a.origin !== b.origin) return;
        var c = a.data.slice(0, 8),
            d = a.data.slice(8, 9),
            e = a.data.slice(9);
        if (c !== b.window_id) return;
        switch (d) {
        case "s":
            b.iframeObj.loaded(), b.postMessage("s", JSON.stringify([y.version, b.protocol, b.trans_url, b.base_url]));
            break;
        case "t":
            b.ri._didMessage(e)
        }
    }, L.prototype.postMessage = function(a, b) {
        var c = this;
        c.iframeObj.post(c.window_id + a + (b || ""), c.origin)
    }, L.prototype.doSend = function(a) {
        this.postMessage("m", a)
    }, L.enabled = function() {
        var a = navigator && navigator.userAgent && navigator.userAgent.indexOf("Konqueror") !== -1;
        return (typeof b.postMessage == "function" || typeof b.postMessage == "object") && !a
    };
    var M, N = function(a, d) {
            parent !== b ? parent.postMessage(M + a + (d || ""), "*") : c.log("Can‘t postMessage, no parent window.", a, d)
        },
        O = function() {};
    O.prototype._didClose = function(a, b) {
        N("t", c.closeFrame(a, b))
    }, O.prototype._didMessage = function(a) {
        N("t", a)
    }, O.prototype._doSend = function(a) {
        this._transport.doSend(a)
    }, O.prototype._doCleanup = function() {
        this._transport.doCleanup()
    }, c.parent_origin = undefined, y.bootstrap_iframe = function() {
        var d;
        M = a.location.hash.slice(1);
        var e = function(a) {
                if (a.source !== parent) return;
                typeof c.parent_origin == "undefined" && (c.parent_origin = a.origin);
                if (a.origin !== c.parent_origin) return;
                var e = a.data.slice(0, 8),
                    f = a.data.slice(8, 9),
                    g = a.data.slice(9);
                if (e !== M) return;
                switch (f) {
                case "s":
                    var h = JSON.parse(g),
                        i = h[0],
                        j = h[1],
                        k = h[2],
                        l = h[3];
                    i !== y.version && c.log(‘Incompatibile SockJS! Main site uses: "‘ + i + ‘", the iframe:‘ + ‘ "‘ + y.version + ‘".‘);
                    if (!c.flatUrl(k) || !c.flatUrl(l)) {
                        c.log("Only basic urls are supported in SockJS");
                        return
                    }
                    if (!c.isSameOriginUrl(k) || !c.isSameOriginUrl(l)) {
                        c.log("Can‘t connect to different domain from within an iframe. (" + JSON.stringify([b.location.href, k, l]) + ")");
                        return
                    }
                    d = new O, d._transport = new O[j](d, k, l);
                    break;
                case "m":
                    d._doSend(g);
                    break;
                case "c":
                    d && d._doCleanup(), d = null
                }
            };
        c.attachMessage(e), N("s")
    };
    var P = function(a, b) {
            var d = this;
            c.delay(function() {
                d.doXhr(a, b)
            })
        };
    P.prototype = new f(["finish"]), P.prototype.doXhr = function(a, b) {
        var d = this,
            e = (new Date).getTime(),
            f = new b("GET", a + "/info"),
            g = c.delay(8e3, function() {
                f.ontimeout()
            });
        f.onfinish = function(a, b) {
            clearTimeout(g), g = null;
            if (a === 200) {
                var c = (new Date).getTime() - e,
                    f = JSON.parse(b);
                typeof f != "object" && (f = {}), d.emit("finish", f, c)
            } else d.emit("finish")
        }, f.ontimeout = function() {
            f.close(), d.emit("finish")
        }
    };
    var Q = function(b) {
            var d = this,
                e = function() {
                    var a = new L;
                    a.protocol = "w-iframe-info-receiver";
                    var c = function(b) {
                            if (typeof b == "string" && b.substr(0, 1) === "m") {
                                var c = JSON.parse(b.substr(1)),
                                    e = c[0],
                                    f = c[1];
                                d.emit("finish", e, f)
                            } else d.emit("finish");
                            a.doCleanup(), a = null
                        },
                        e = {
                            _options: {},
                            _didClose: c,
                            _didMessage: c
                        };
                    a.i_constructor(e, b, b)
                };
            a.body ? e() : c.attachEvent("load", e)
        };
    Q.prototype = new f(["finish"]);
    var R = function() {
            var a = this;
            c.delay(function() {
                a.emit("finish", {}, 2e3)
            })
        };
    R.prototype = new f(["finish"]);
    var S = function(a) {
            if (c.isSameOriginUrl(a)) return new P(a, c.XHRLocalObject);
            switch (c.isXHRCorsCapable()) {
            case 1:
                return new P(a, c.XHRLocalObject);
            case 2:
                return new P(a, c.XDRObject);
            case 3:
                return new Q(a);
            default:
                return new R
            }
        },
        T = O["w-iframe-info-receiver"] = function(a, b, d) {
            var e = new P(d, c.XHRLocalObject);
            e.onfinish = function(b, c) {
                a._didMessage("m" + JSON.stringify([b, c])), a._didClose()
            }
        };
    T.prototype.doCleanup = function() {};
    var U = y["iframe-eventsource"] = function() {
            var a = this;
            a.protocol = "w-iframe-eventsource", a.i_constructor.apply(a, arguments)
        };
    U.prototype = new L, U.enabled = function() {
        return "EventSource" in b && L.enabled()
    }, U.need_body = !0, U.roundTrips = 3;
    var V = O["w-iframe-eventsource"] = function(a, b) {
            this.run(a, b, "/eventsource", _, c.XHRLocalObject)
        };
    V.prototype = new G;
    var W = y["iframe-xhr-polling"] = function() {
            var a = this;
            a.protocol = "w-iframe-xhr-polling", a.i_constructor.apply(a, arguments)
        };
    W.prototype = new L, W.enabled = function() {
        return b.XMLHttpRequest && L.enabled()
    }, W.need_body = !0, W.roundTrips = 3;
    var X = O["w-iframe-xhr-polling"] = function(a, b) {
            this.run(a, b, "/xhr", bd, c.XHRLocalObject)
        };
    X.prototype = new G;
    var Y = y["iframe-htmlfile"] = function() {
            var a = this;
            a.protocol = "w-iframe-htmlfile", a.i_constructor.apply(a, arguments)
        };
    Y.prototype = new L, Y.enabled = function() {
        return L.enabled()
    }, Y.need_body = !0, Y.roundTrips = 3;
    var Z = O["w-iframe-htmlfile"] = function(a, b) {
            this.run(a, b, "/htmlfile", bc, c.XHRLocalObject)
        };
    Z.prototype = new G;
    var $ = function(a, b, c, d) {
            var e = this;
            e.ri = a, e.Receiver = b, e.recv_url = c, e.AjaxObject = d, e._scheduleRecv()
        };
    $.prototype._scheduleRecv = function() {
        var a = this,
            b = a.poll = new a.Receiver(a.recv_url, a.AjaxObject),
            c = 0;
        b.onmessage = function(b) {
            c += 1, a.ri._didMessage(b.data)
        }, b.onclose = function(c) {
            a.poll = b = b.onmessage = b.onclose = null, a.poll_is_closing || (c.reason === "permanent" ? a.ri._didClose(1006, "Polling error (" + c.reason + ")") : a._scheduleRecv())
        }
    }, $.prototype.abort = function() {
        var a = this;
        a.poll_is_closing = !0, a.poll && a.poll.abort()
    };
    var _ = function(a) {
            var b = this,
                d = new EventSource(a);
            d.onmessage = function(a) {
                b.dispatchEvent(new e("message", {
                    data: unescape(a.data)
                }))
            }, b.es_close = d.onerror = function(a, f) {
                var g = f ? "user" : d.readyState !== 2 ? "network" : "permanent";
                b.es_close = d.onmessage = d.onerror = null, d.close(), d = null, c.delay(200, function() {
                    b.dispatchEvent(new e("close", {
                        reason: g
                    }))
                })
            }
        };
    _.prototype = new d, _.prototype.abort = function() {
        var a = this;
        a.es_close && a.es_close({}, !0)
    };
    var ba, bb = function() {
            if (ba === undefined) if ("ActiveXObject" in b) try {
                ba = !! (new ActiveXObject("htmlfile"))
            } catch (a) {} else ba = !1;
            return ba
        },
        bc = function(a) {
            var d = this;
            c.polluteGlobalNamespace(), d.id = "a" + c.random_string(6, 26), a += (a.indexOf("?") === -1 ? "?" : "&") + "c=" + escape(h + "." + d.id);
            var f = bb() ? c.createHtmlfile : c.createIframe,
                g;
            b[h][d.id] = {
                start: function() {
                    g.loaded()
                },
                message: function(a) {
                    d.dispatchEvent(new e("message", {
                        data: a
                    }))
                },
                stop: function() {
                    d.iframe_close({}, "network")
                }
            }, d.iframe_close = function(a, c) {
                g.cleanup(), d.iframe_close = g = null, delete b[h][d.id], d.dispatchEvent(new e("close", {
                    reason: c
                }))
            }, g = f(a, function(a) {
                d.iframe_close({}, "permanent")
            })
        };
    bc.prototype = new d, bc.prototype.abort = function() {
        var a = this;
        a.iframe_close && a.iframe_close({}, "user")
    };
    var bd = function(a, b) {
            var c = this,
                d = 0;
            c.xo = new b("POST", a, null), c.xo.onchunk = function(a, b) {
                if (a !== 200) return;
                for (;;) {
                    var f = b.slice(d),
                        g = f.indexOf("\n");
                    if (g === -1) break;
                    d += g + 1;
                    var h = f.slice(0, g);
                    c.dispatchEvent(new e("message", {
                        data: h
                    }))
                }
            }, c.xo.onfinish = function(a, b) {
                c.xo.onchunk(a, b), c.xo = null;
                var d = a === 200 ? "network" : "permanent";
                c.dispatchEvent(new e("close", {
                    reason: d
                }))
            }
        };
    return bd.prototype = new d, bd.prototype.abort = function() {
        var a = this;
        a.xo && (a.xo.close(), a.dispatchEvent(new e("close", {
            reason: "user"
        })), a.xo = null)
    }, y.getUtils = function() {
        return c
    }, y.getIframeTransport = function() {
        return L
    }, y
}(), "_sockjs_onload" in window && setTimeout(_sockjs_onload, 1), typeof define == "function" && define.amd && define("sockjs", [], function() {
    return SockJS
});
SockJS.getUtils().log(‘*** SockJS CDN is being retired on Dec 1st *** Please transition to a public CDN. See https://github.com/sockjs/sockjs-client/issues/198 for more information.‘);
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="shortcut icon" href="favicon.ico">
<title></title>
<style type="text/css">
#connect-container {
    float: left;
    width: 400px
}

#connect-container div {
    padding: 5px;
}

#console-container {
    float: left;
    margin-left: 15px;
    width: 400px;
}

#console {
    border: 1px solid #CCCCCC;
    border-right-color: #999999;
    border-bottom-color: #999999;
    height: 170px;
    overflow-y: scroll;
    padding: 5px;
    width: 100%;
}

#console p {
    padding: 0;
    margin: 0;
}
</style>

<script src="js/sockjs-0.3.js"></script>

<script type="text/javascript">
        var ws = null;
        var url = null;
        var transports = [];  

        function setConnected(connected) {
            document.getElementById(‘connect‘).disabled = connected;
            document.getElementById(‘disconnect‘).disabled = !connected;
            document.getElementById(‘echo‘).disabled = !connected;
        }  

        function connect() {
            url = ‘ws://‘ + window.location.host + ‘/项目名/websocket‘;  

            ws = (url.indexOf(‘sockjs‘) != -1) ?
                new SockJS(url, undefined, {protocols_whitelist: transports}) : new WebSocket(url);  

            ws.onopen = function () {
                setConnected(true);
                log(‘建立连接‘);
            };
            ws.onmessage = function (event) {
                log(‘ 收到: ‘ + event.data);
            };
            ws.onclose = function (event) {
                setConnected(false);
                log(‘连接关闭‘);
                log(event);
            };
        }  

        function disconnect() {
            if (ws != null) {
                ws.close();
                ws = null;
            }
            setConnected(false);
        }  

        function echo() {
            if (ws != null) {
                var message = document.getElementById(‘sendmessage‘).value;
                log(‘发送: ‘ + message);
                ws.send(message);
            } else {
                alert(‘连接未建立,请连接‘);
            }
        }
        function updateTransport(transport) {
            alert(transport);
          transports = (transport == ‘all‘) ?  [] : [transport];
        }  

        function log(message) {
            var console = document.getElementById(‘console‘);
            var p = document.createElement(‘p‘);
            p.style.wordWrap = ‘break-word‘;
            p.appendChild(document.createTextNode(message));
            console.appendChild(p);
            while (console.childNodes.length > 25) {
                console.removeChild(console.firstChild);
            }
            console.scrollTop = console.scrollHeight;
            flashTitlePlayer.start("【新消息提醒】");
        }
        function st(){
             flashTitlePlayer.stop();
        }
    </script>
</head>
<body>
<hr/>
    <noscript>
        <h2 style="color: #ff0000">似乎你的浏览器不支持JavaScript!WebSockets依靠JavaScript启用。拜托启用JavaScript并重新加载此页!</h2>
    </noscript>
    <div>
        <div id="connect-container">
            <div>
                <button id="connect" onclick="connect();">连接</button>
                <button id="disconnect" disabled="disabled" onclick="disconnect();">断开</button>
            </div>
            <div>
                <textarea id="sendmessage" style="width: 350px">请输入文字!</textarea>
            </div>
            <div>
                <button id="echo" onclick="echo();" disabled="disabled">发送消息</button>
            </div>
        </div>
        <div id="console-container">
            <div id="console"></div>
        </div>
    </div>
</body>
</html>    

备注:

web.xml导入

xmlns:websocket="http://www.springframework.org/schema/websocket"

http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"
id="WebApp_ID" version="2.5"

==============================================================================================================================================

调用如上方式实现最简单的Websocket。多方加入发送信息测试;未经过性能处理,只可承受千级并发量!

==============================================================================================================================================

页面引入js.

时间: 2024-11-07 18:12:47

WebSocket 最简单的用法的相关文章

基于html5 localStorage , web SQL, websocket的简单聊天程序

new function() { var ws = null; var connected = false; var serverUrl; var connectionStatus; var sendMessage; var connectButton; var disconnectButton; var sendButton; var open = function() { var url = serverUrl.val(); ws = new WebSocket(url); ws.onope

模拟java.util.Collection一些简单的用法

/* 需求:模拟java.util.Collection一些简单的用法! 注意:java虚拟机中并没有泛型类型的对象.泛型是通过编译器执行一个被称为类型擦除的前段转换来实现的. 1)用泛型的原生类型替代泛型. 原生类型是泛型中去掉尖括号及其中的类型参数的类或接口.泛型中所有对类型变量的引用都替换为类型变量的最近上限类型, 如对于Cage<T extends Animal>, T的引用将用Animal替换,而对于Cage<T>, T 的引用将用Object替换. 2) */ inte

websocket(二) websocket的简单实现,识别用户属性的群聊

没什么好说的,websocket实现非常简单,我们直接看代码. 运行环境:jdk8 tomcat8 无须其他jar包. 具体环境支持自己百度 package com.reach.socketController; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.concurrent.CopyOnWriteArraySet; import javax.annot

Tinyxml简单使用法

1.概要介绍一下: 尝试了tinyxml,rapidxml,libxml2等3中第3方库,前两者相对较为轻量级,libxml2非常完善,强大. 这是网上总结出来的优缺点: 1.tinyxml当节点内容的空而使用GetText()方法时候会出错 2.rapidxml编码问题不是特别好 3.libxml2对内存释放要求较高,否则时常遇到core dump. TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译.这个解析库的模型通过解析XML文件,然后在

websocket实现简单聊天程序

程序的流程图: 主要代码: 服务端 app.js 先加载所需要的通信模块: var express = require('express'); var app = express(); var http = require('http').createServer(app); var io = require('socket.io').listen(http); var fs = require('fs'); 创建用户列表和消息列表: var person = []; var history =

VSFTPD简单的用法

在公司的业务中,有一些常用的软件是公开使用的,比如XSHELL这一些常用的,用的时候总不能在去下载吧!!!所以公司中就会搭建一些共享服务器等,本次介绍的就是VSFTPD的用法 (本次要求,将vsftpd做出来,实现匿名用户可以上传) 客户机可以从服务器上上传下载     192.168.1.100     ---------->     192.168.1.1    pc客户机----------------------------ftp服务器 第一步,安装软件包本次采用yum的方式安装,也可以

用swoole和websocket开发简单聊天室

首先,我想说下写代码的一些习惯,第一,任何可配置的参数或变量都要写到一个config文件中.第二,代码中一定要有日志记录和完善的报错并记录报错.言归正传,swoole应该是每个phper必须要了解的,它号称重新定义了php.此聊天室利用了swoole高并发并且异步非阻塞的特点提高了程序的性能. 首先,定义一个 swoole_lock 和 swoole_websocket_server ,并且配置参数,具体参数详情可以去swoole官网查看. public function start(){ $t

websocket的简单使用

一 轮询 什么是轮询:设置每一段时间去访问一次服务器,然后服务器返回最新的数据.这样服务器的压力会非常的大,并且还会有延迟.适用于小型程序. 实现:再客户端的页面设置一个定时发送请求的任务,每个这段时间就要发送一个请求,来获取最新的数据 实例: app.py from flask import Flask,render_template app = Flask(__name__) @app.route('/index') def index(): return render_template('

Unity中Websocket的简单使用

首先我们需要一个websocket服务器,之前的博文中有做Tomcat架设简单Websocket服务器用的时候打开就行了,先不管它 Unity中新建场景建UI(UGUI)有一个连接按钮Button一个信息输入框InputField一个发送按钮Button一个断开按钮Button一个消息显示框Text 场景中建一个GameObject,在上面加个脚本,就叫WSMgr好了用到了BestHTTP这个插件 using System.Collections; using System.Collection