Advertisement
Serafim

Untitled

Jul 12th, 2013
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class ConnectionTriggerCollection extends Std
  2.   [$this, self] = [@::$this, @::self]
  3.   @::private
  4.     iterator: 0
  5.     prefix:   'Resource#'
  6.  
  7.   constructor: ->
  8.     @callbacks = []
  9.  
  10.   flushIterator: ->
  11.     $this.iterator = 0
  12.  
  13.   push: (cb) ->
  14.     id  = $this.prefix + (++$this.iterator)
  15.     @callbacks[id] = cb
  16.     return {
  17.       id: id,
  18.       status: true
  19.       remove: =>
  20.         @remove(id)
  21.         @status = false
  22.     }
  23.  
  24.   call: (args) ->
  25.     @callbacks[i](args) for i of @callbacks
  26.  
  27.   remove: (id) ->
  28.     if typeof @callbacks[id] is "function"
  29.       delete @callbacks[id]
  30.       return true
  31.     throw new Exception("Can not find trigger #{id}")
  32.     return false
  33.  
  34. window.ConnectionTriggerCollection = ConnectionTriggerCollection
  35.  
  36. ###
  37.   Класс соединения с сервером
  38. ###
  39. class Connection
  40.   # Время реконнекта при обрыве соединения
  41.   @RECONNECT_TIMEOUT  = if App.config.develop then 1 else 60000
  42.   # Отображать ли логи сокета
  43.   @SHOW_LOGS          = true
  44.  
  45.  
  46.   ###
  47.     Сообщения логов
  48.     @string: Logs
  49.   ###
  50.   @LOG_CREATE         = 'Создание соединения:'
  51.   @LOG_OPEN           = 'Выполнено подключение к сокету.'
  52.   @LOG_CLOSE          = 'Отклюение сокета.'
  53.   @LOG_ERROR          = 'Сервер не отвечает.'
  54.   @LOG_RECONNECT      = 'Переподключение к серверу после ' + @RECONNECT_TIMEOUT + ' миллисекунд.'
  55.   @LOG_INPUT_MESSAGE  = 'Ответ сокета:'
  56.   @LOG_OUTPUT_MESSAGE = 'Отправка сообщения:'
  57.   @LOG_SET_TIMEOUT    = 'Смена таймаута переподключения к серверу: '
  58.  
  59.   ###
  60.     Ошибки
  61.   ###
  62.   @ERR_MESSAGE_SEND   = 'Невозможно отправить сообщение. Нет подключения к серверу.'
  63.   @ERR_SOCKET_CLOSE   = 'Невозможно закрыть соединение. Соединение отсутствует.'
  64.  
  65.   ###
  66.     Статусы сокета
  67.     @string: Status
  68.   ###
  69.   @STATUS_CLOSED      = 'STATUS_CLOSED'
  70.   @STATUS_CONNECTED   = 'STATUS_CONNECTED'
  71.  
  72.  
  73.   ###
  74.     Создание нового соединения
  75.     @string host: Адрес соединения
  76.     @string id: Идентификатор соединения
  77.     @return object Connection
  78.   ###
  79.   constructor: (host, id = undefined) ->
  80.     # Кодировать ли данные сокета
  81.     @encode   = true
  82.     #
  83.     # ID соединения
  84.     @id = if id is undefined then id = Utils.uniqueId('', 4) else id
  85.     # Хост (адрес) соединения
  86.     @host     = host
  87.     # Объект соединения
  88.     @channel  = {}
  89.     # Триггеры
  90.     @triggers =
  91.       onopen:      new ConnectionTriggerCollection  # открытие
  92.       onclose:     new ConnectionTriggerCollection  # закрытие
  93.       onmessage:   new ConnectionTriggerCollection # входящее сообщение
  94.       onreconnect: new ConnectionTriggerCollection
  95.  
  96.     # Одноразовые триггеры (срабатывают один раз)
  97.     @onceTriggers =
  98.       onopen:   []  # открытие
  99.       onclose:  []  # закрытие
  100.       onmessage:[]  # входящее сообщение
  101.       onreconnect: []
  102.  
  103.     # Текущий статус соединения
  104.     @status   = Connection.STATUS_CLOSED
  105.  
  106.   setReconnectTimeout: (time) ->
  107.     @log(Connection.LOG_SET_TIMEOUT, time)
  108.     Connection.RECONNECT_TIMEOUT = time
  109.  
  110.   ###
  111.     Подключение к серверу
  112.     @callable cb: Коллбек на откртие
  113.   ###
  114.   connect: (cb = (->))->
  115.     @log(Connection.LOG_CREATE, @host)
  116.     delete @channel
  117.     @channel = new WebSocket(@host)
  118.  
  119.  
  120.     @channel.onopen = (event) =>
  121.       @log(Connection.LOG_OPEN, event)
  122.       @status   = Connection.STATUS_CONNECTED
  123.       cb()
  124.       @triggers.onopen.call event
  125.       @onceTriggers.onopen.each (foo) -> foo(event)
  126.       @onceTriggers.onopen = []
  127.  
  128.  
  129.     @channel.onmessage = (event) =>
  130.       message = if @encode then Utils.decodeData(event.data.replace(/\n/g, '')) else event.data
  131.       @log(Connection.LOG_INPUT_MESSAGE, message)
  132.       @triggers.onmessage.call message
  133.       @onceTriggers.onmessage.each (foo) -> foo(message)
  134.       @onceTriggers.onmessage = []
  135.  
  136.  
  137.     @channel.onclose = (event) =>
  138.       @log(Connection.LOG_CLOSE, event)
  139.       @status   = Connection.STATUS_CLOSED
  140.       @triggers.onclose.call event
  141.       @onceTriggers.onclose.each (foo) -> foo(event)
  142.       @onceTriggers.onclose = []
  143.  
  144.       # RECONNECT
  145.       @log(Connection.LOG_RECONNECT, @host)
  146.       if @reconnectTimeout then clearTimeout(@reconnectTimeout)
  147.       @reconnectTimeout = setTimeout =>
  148.         delete @reconnectTimeout
  149.         @reconnect(event)
  150.       , Connection.RECONNECT_TIMEOUT
  151.  
  152.   ###
  153.     Переподключение соединения
  154.     @return $this
  155.   ###
  156.   reconnect: (event) ->
  157.     if @status is Connection.STATUS_CONNECTED
  158.       @channel.close()
  159.     else
  160.       @connect()
  161.     @waitOpen =>
  162.       @triggers.onreconnect.call event
  163.       @onceTriggers.onreconnect.each (foo) -> foo(event)
  164.       @onceTriggers.onreconnect = []
  165.     return @
  166.  
  167.   ###
  168.     Добавление триггера на открытие соединения
  169.     @callable trigger: Коллбэк
  170.     @return $this
  171.   ###
  172.   onopen: (trigger) ->
  173.     return @triggers.onopen.push trigger
  174.  
  175.   # @alias onopen: Срабатывает только один раз
  176.   waitOpen: (trigger) ->
  177.     @onceTriggers.onopen.push trigger
  178.     return @
  179.  
  180.   ###
  181.     Добавление триггера на переподключение соединения
  182.     @callable trigger: Коллбэк
  183.     @return $this
  184.   ###
  185.   onreconnect: (trigger) ->
  186.     return @triggers.onreconnect.push trigger
  187.  
  188.   # @alias onopen: Срабатывает только один раз
  189.   waitReconnect: (trigger) ->
  190.     @onceTriggers.onreconnect.push trigger
  191.     return @
  192.  
  193.   ###
  194.     Добавление триггера на закрытие соединения
  195.     @callable trigger: Коллбэк
  196.     @return $this
  197.   ###
  198.   onclose: (trigger) ->
  199.     return @triggers.onclose.push trigger
  200.  
  201.   # @alias onclose: Срабатывает один раз
  202.   waitClose: (trigger) ->
  203.     @onceTriggers.onclose.push trigger
  204.     return @
  205.  
  206.   ###
  207.     Добавление триггера на входящие сообщения
  208.     @callable trigger: Коллбэк
  209.     @return $this
  210.   ###
  211.   onmessage: (trigger) ->
  212.     return @triggers.onmessage.push trigger
  213.  
  214.   # @alias onmessage: Срабатывает один раз
  215.   waitMessage: (trigger) ->
  216.     @onceTriggers.onmessage.push trigger
  217.     return @
  218.  
  219.   ###
  220.     Отправка сообщения в открытый сокет
  221.     @string || @object message: Данные для отправки
  222.     @return $this
  223.   ###
  224.   send: (message, encode = @encode) ->
  225.     if @status is Connection.STATUS_CONNECTED
  226.       @log(Connection.LOG_OUTPUT_MESSAGE, message)
  227.       if encode then message = Utils.encodeData(message)
  228.       @channel.send message
  229.     else
  230.       @log(Connection.ERR_MESSAGE_SEND, "status: #{@status}")
  231.     return @
  232.  
  233.  
  234.   ###
  235.     Закрытие соединения
  236.     @return $this
  237.   ###
  238.   close: ->
  239.     if @status is Connection.STATUS_CONNECTED
  240.       @channel.close()
  241.     else
  242.       @log(Connection.ERR_SOCKET_CLOSE, "status: #{@status}")
  243.     return @
  244.  
  245.  
  246.   ###
  247.     Логгирование сокета
  248.     @string logName: Сообщение лога
  249.     @mixed data: Данные описания лога
  250.   ###
  251.   log: (logName, data) =>
  252.     if Connection.SHOW_LOGS then p "WebSocket [#{@id}]: #{logName}", data
  253.  
  254.  
  255. class Server
  256.   constructor: ->
  257.     @corruption   = new Connection(App.config.websocket, 'Corruption')
  258.     @chat         = new Connection(App.config.chatWebsocket, 'Chat')
  259.  
  260.   ###
  261.     Методы соединения с сокетом
  262.     добавляем в объект сервера
  263.   ###
  264.   onopen: (trigger) -> @corruption.onopen trigger
  265.   onclose: (trigger) -> @corruption.onclose trigger
  266.   onmessage: (trigger) -> @corruption.onmessage trigger
  267.   close: -> @corruption.close()
  268.   send: (message) -> @corruption.send message
  269.  
  270.   ###
  271.     Отправка get запроса на сервер
  272.     @string path: Путь
  273.     @object data: Данные
  274.     @callable cb: Коллбек
  275.     @return $this
  276.   ###
  277.   get: (path = '', data = {}, cb = (->), fail = (->)) ->
  278.     p 'GET: ', path
  279.     $.get(App.config.url + '/' + path + '?cache=' + Utils.uniqueId(), data, (j) ->
  280.       cb(Server.alaxDecorate(path, j))
  281.     ).fail => fail()
  282.  
  283.     return @
  284.  
  285.   ###
  286.     Отправка post запроса на сервер
  287.     @string path: Путь
  288.     @object data: Данные
  289.     @callable cb: Коллбек
  290.     @return $this
  291.   ###
  292.   post: (path = '', data = {}, cb = (->), fail = (->)) ->
  293.     p 'POST: ', path
  294.     $.post(App.config.url + '/' + path + '?cache=' + Utils.uniqueId(), data, (j) ->
  295.       cb(Server.alaxDecorate(path, j))
  296.     ).fail => fail()
  297.     return @
  298.  
  299.   ###
  300.     Отправка put запроса на сервер
  301.     @string path: Путь
  302.     @object data: Данные
  303.     @callable cb: Коллбек
  304.     @return $this
  305.   ###
  306.   put: (path = '', data = {}, cb = (->), fail = (->)) ->
  307.     p 'PUT: ', path
  308.     $.ajax(
  309.       url: App.config.url + '/' + path
  310.       type: 'PUT'
  311.       cache: false
  312.       data: data
  313.       success: (response) =>
  314.         cb(response)
  315.     ).fail => fail()
  316.     return @
  317.  
  318.   ###
  319.     * Преобразование json строки в объект при ошибке хедеров сервера
  320.     * Установка стандартных значений для запросов, возвращаюх ошибку доступа
  321.     @string name: Название json файла
  322.     @object data:
  323.   ###
  324.   @alaxDecorate: (name, data) ->
  325.     data = if typeof data is 'object' then data else JSON.parse(data)
  326.     if data.status && data.message && data.status is "failed"
  327.       switch name
  328.         when "account.json"
  329.           return {}
  330.         when "account/properties.json"
  331.           return {blocks:{},buildings:[],expenses:0,items:{},missions:{},perks:{}}
  332.         when "blocks.json"
  333.           return {blocks:[]}
  334.         when "collisions.json"
  335.           return {targets:[]}
  336.         when "chains/members.json"
  337.           return {followers:[],followings:[]}
  338.         when "hitlists.json"
  339.           return {targets:[]}
  340.         when "perks/shop.json"
  341.           return {perks:[], talants_price:[]}
  342.         when "perks.json"
  343.           return {achievements:[],avaliable_slots:0,discounts:{items:0,buildings:0},fake_friends:0,purchased:[]}
  344.         when "activities.json"
  345.           return {}
  346.         else throw new Error('Необработанный json ответ сервера')
  347.       console.log("JSON Error: Для " + name + " вернулся ответ ошибки доступа")
  348.     else
  349.       return data
  350.  
  351.  
  352. window.Server = Server
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement