Подробности будут тут http://vk.com/club34256705
В конце концов оказался же в этом городе Я!
Я больше не занимаюсь FreeSWITCH по нескольким причинам. Первая - я теперь не сетевой администратор с горкой АТС, и не работаю в VoIP стартапе.
Вторая - считаю разработчиков FreeSWITCH-а неадекватными по нескольким пунктам.
1. Прием патчей. Когда у нас глюкало видео я искал проблему и нашел ее. Создал патч и отправил в жиру. После месяца боданий патч был принят с формулировкой "а предыдущий пацанчик говорил что все работает отлично, но вы достали, хрен с вами". Многообщающе.
2. Использование DMCA для блокировки репозитория с кодом g729 кодека. Нормальные люди вначале пишут и говорят - у вас тут мои копирайты, вы поправьте. В общем мне их мотивировка неясна - их права никак не были нарушены, но шило в попе творит чудеса.
В общем как для профессионального разработчика для меня FreeSWITCH это один сплошной дурдом. Без причин с ним возиться я с ним возиться никакого желания не имею.
from twisted.internet import defer, protocol, reactor
from tx_green import inlineCallbacks
from greentokyo import Tyrant
@inlineCallbacks
def test_proto():
t = Tyrant()
print t.get_stats()
t['kuku'] = 'Green Tyrant!'
print t['kuku']
reactor.stop()
if __name__=='__main__':
test_proto()
reactor.run()
class MemcacheProtocol(LineOnlyReceiver):
"""
Реализует базис протокола - прием сообщений от клиента
и отдачу результата.
"""
def lineReceived(self,line):
debug(repr(line))
if not 'parameters' in self.instruction:
parameters = line.split(' ')
debug("Got new command "+parameters[0])
self.instruction['parameters']=parameters
# Если данных не ожидается, то к исполнению
if parameters[0] in Cache.oneline_commands:
self.process()
else:
# Получены данные к двухстрочной команде, к исполнению
debug("Got data "+line)
self.instruction['data']=line
self.process()
def process(self):
# Cache.call возвращает генератор
for line in Cache.call(self.instruction):
# И мы отсылаем все что он нагенерирует отдельными строками
debug("Send line "+line)
self.sendLine(line)
# Готовы к дальнейшим инструкциям, насяльника!
self.instruction={}
def connectionMade(self):
debug("Connected!")
self.instruction={}
Команды записи данных:Реализация разбора:[noreply]\r\n cas [noreply]\r\n Получение данных: get *\r\n gets *\r\n delete \r\n Ну и тому подобное.
class Instruction(object):
def __init__(self, i):
p = i['parameters']
self.cmd = p.pop(0)
# Проверяем noreply
if p[-1]=='noreply':
self.reply=False
# Выкидываем его
p.pop(-1)
else:
self.reply=True
if self.cmd in Cache.storage_commands:
# Если CAS то есть еще один параметр (т.е. особый случай)
if self.cmd == "cas":
self.unique = p.pop(-1)
# Теперь все параметры однозначны, но мы хотим расширить протокол,
# потому все не так просто, как dict(zip())
self.bytes = p.pop(-1)
self.exptime = p.pop(-1)
self.flags = p.pop(-1)
self.data = i.get('data',None)
# incr, decr
elif self.cmd in ["incr","decr"]:
self.change_value = p.pop(-1)
self.keys = p
def __str__(self):
return str(self.__dict__)
class Cache(object):
# consts
storage_commands = ["set", "add", "replace", "append", "prepend","cas"]
oneline_commands = ["get", "gets","getn", "delete", "incr", "decr", "stats"]
# cache storage
data = Entry(0,0,0)
# cache operations
@classmethod
def call(cls, instruction):
i = Instruction(instruction)
debug(i)
command = getattr(cls,i.cmd)
return command(i)
@classmethod
def set(cls, i):
"set, поддержка вложенных ключей"
parent = cls.data.get_child(i.keys[:-1])
if parent:
parent.set_child(i.keys[-1], Entry(i.data,i.flags,i.exptime))
yield "STORED"
else:
yield "NOT_STORED"
@classmethod
def get(cls, i):
"get, не обрабатывает вложенные ключи"
for key in i.keys:
entry = cls.data.get_child([key])
if entry:
yield ' '.join(( "VALUE", key, entry.flags, str(len(entry.data)) ))
yield entry.data
yield "END"
#!/usr/bin/env python
# coding: utf-8
from twisted.application import internet, service
import sip
DOMAIN='192.168.9.5'
application = service.Application("JuzzCallBack")
sip.RegisterProxy.registry = sip.InMemoryRegistry(DOMAIN)
sip.RegisterProxy.locator = sip.RegisterProxy.registry
sip.RegisterProxy.debug = True
proxy = internet.UDPServer(5060,sip.RegisterProxy())
proxy.setServiceParent(application)