发现身边很多朋友都在学习Python,而Python作为一个计算语言,很少有练习的机会,今天开放一个之前给广州客户做的消息中间件源码,读懂这套代码基本上就会应用Python,包括了:

1、websocket 

2、类与对象

3、多线程

4、日志处理

5、json处理

6、时间处理

7、MySQL数据库处理

8、HTTP request 处理

9、头文件引用


一、定义配置文件 uncall_config.py

  1. __author__ = 'ideacall'
  2.  
  3. LISTEN_IP =  "xx.xx.xx.xx"
  4. LISTEN_PORT = 6899
  5.  
  6. HOST= ""
  7. PORT=3306
  8. USER='root'
  9. PASSWD=''
  10. DB=''
  11.  
  12. UNCALL_HTTP_HOST =  ""



二、主文件


  1. #coding=utf8
  2. #!/usr/bin/python
  3.  
  4. from __future__ import print_function
  5. import struct,socket
  6. import hashlib
  7. import threading,random
  8. import time
  9. import json
  10. import pymysql
  11. from base64 import b64encode, b64decode
  12. import urllib  
  13. import uncall_config
  14. from time import ctime,sleep
  15.  
  16. SEND_BUF_SIZE = 4096 # send buf
  17. RECV_BUF_SIZE = 4096 # recv buf
  18.  
  19. LISTEN_IP = uncall_config.LISTEN_IP #listen ip address
  20. LISTEN_PORT = uncall_config.LISTEN_PORT #listen ip ports
  21. HOST = uncall_config.HOST #db host
  22. PORT = uncall_config.PORT #db port
  23. USER = uncall_config.USER #db user
  24. PASSWD = uncall_config.PASSWD #db pwd
  25. DB = uncall_config.DB # db datanames
  26. UNCALL_HTTP_HOST = uncall_config.UNCALL_HTTP_HOST #uncallcc webservices address
  27.  
  28. connectionlist = {}
  29. webclasslist = {}
  30. pymysql.install_as_MySQLdb()
  31.  
  32. def write_log(msg):
  33.     f=open("/tmp/cxst_socket.log","a+")
  34.     f.write(msg+"\n")
  35.     f.close()
  36.  
  37. #check number strip is 0
  38. def str_number_strip_check(s):
  39.     if (s.startswith('01')) :
  40.         return s.strip('0')
  41.     else:
  42.         return s
  43.  
  44. #check exten login
  45. def check_extension(extension):
  46.     rows = 0
  47.     conn = pymysql.connect(host=HOST, port=PORT,user=USER,passwd=PASSWD,db=DB)
  48.     cur = conn.cursor()
  49.     cur.execute("select extension, status, dnd from users where extension='"+str(extension)+"'")
  50.     rows = cur.rowcount
  51.     cur.close()
  52.     conn.close()
  53.     return rows
  54.  
  55. def pushData():
  56.  
  57.     global webclasslist
  58.  
  59.     for webclient in webclasslist.values():
  60.  
  61.         write_log(' TASK THREAD -----> %s is_login status %s %s ' %(webclient.index, webclient.is_login, webclient.extension))
  62.  
  63.         if webclient.is_login > 0 :
  64.  
  65.             status = get_extension_status(webclient.extension)
  66.  
  67.             if status != webclient.status and len(status)>0 :
  68.                 webclient.status = status
  69.                 ret_data = {'Event':'STATUS','errorCode':'E0','errorMsg':'SUCCESS','data':status}
  70.                 sendMessageIndex(json.dumps(ret_data),webclient.index)
  71.  
  72.             pop_list_callin = get_extension_pop_callin(webclient.extension)
  73.             if len(pop_list_callin) >0 :
  74.                 sendMessageIndex(json.dumps(pop_list_callin),webclient.index)
  75.  
  76.             pop_list_callout = get_extension_pop_callout(webclient.extension)
  77.             if len(pop_list_callout) >0 :
  78.                 sendMessageIndex(json.dumps(pop_list_callout),webclient.index)
  79.  
  80.             cdr_list = get_extension_cdr(webclient.extension)
  81.             if len(cdr_list):
  82.                 ret_data = {'Event':'CDR','errorCode':'E0','errorMsg':'SUCCESS','data':cdr_list}
  83.                 sendMessageIndex(json.dumps(ret_data),webclient.index)
  84.  
  85.     sleep(3)
  86.  
  87. def data_check():
  88.     while True:
  89.         pushData()
  90.         sleep(2)
  91.  
  92. def get_extension_status(extension):
  93.  
  94.     conn = pymysql.connect(host=HOST, port=PORT,user=USER,passwd=PASSWD,db=DB)
  95.     cur = conn.cursor()
  96.     cur.execute("SELECT d.device as TerminalId, d.extension as StaffId , FROM_UNIXTIME(d.logintime) as `Time`, u.dnd, u.`status` from asterisk.device_login as d LEFT JOIN asterisk.users as u on u.extension = d.device where d.extension ='"+extension+"'")
  97.     retlist=[]
  98.  
  99.     for r in cur:
  100.         row ={'TerminalId': 'MIDEA'+str(r[0]),'StaffId' : str(r[1]), 'Time': str(r[2]), 'dnd': str(r[3]), 'status': str(r[4])}
  101.         retlist.append(row)
  102.  
  103.     cur.close()
  104.     conn.close()
  105.     return retlist
  106.  
  107. def get_extension_status_all():
  108.  
  109.     conn = pymysql.connect(host=HOST, port=PORT,user=USER,passwd=PASSWD,db=DB)
  110.     cur = conn.cursor()
  111.     cur.execute("SELECT d.device as TerminalId, d.extension as StaffId , FROM_UNIXTIME(d.logintime) as `Time`, u.dnd, u.`status` from asterisk.device_login as d LEFT JOIN asterisk.users as u on u.extension = d.device")
  112.     retlist=[]
  113.  
  114.     for r in cur:
  115.         row ={'TerminalId': 'MIDEA'+str(r[0]),'StaffId' : str(r[1]), 'Time': str(r[2]), 'dnd': str(r[3]), 'status': str(r[4])}
  116.         retlist.append(row)
  117.  
  118.     cur.close()
  119.     conn.close()
  120.     return retlist
  121.  
  122.  
  123. def get_extension_cdr(extension):
  124.  
  125.     retlist =[]
  126.  
  127.     conn = pymysql.connect(host=HOST, port=PORT,user=USER,passwd=PASSWD,db=DB)
  128.     cur = conn.cursor()
  129.     cur_update = conn.cursor()
  130.     cdr_tables = "cdro_"+str(time.strftime("%Y_%-m_%-d",time.localtime()))
  131.     cur.execute("select 1 from information_schema.TABLES where table_name='"+cdr_tables+"'")
  132.  
  133.     if cur.rowcount > 0 :
  134.  
  135.         cur.execute("select src, dst, amaflags, billsec,disposition,uniqueid,userfield,calldate,hangup_src from asteriskcdrdb."+cdr_tables+" where (src ='"+extension+"' or dst = '"+extension+"') and analysis = '0' LIMIT 1")
  136.         for r in cur:
  137.             row ={'src': str_number_strip_check(str(r[0])),'dst' : str_number_strip_check(str(r[1])),'amaflags': str(r[2]),'billsec': str(r[3]),'disposition': str(r[4]),'uniqueid': str(r[5]),'userfield': str(r[6]),'calldate': str(r[7]),'hangup_src': str(r[8])}
  138.             retlist.append(row)
  139.             cur_update.execute("update asteriskcdrdb."+cdr_tables+" set analysis = '1' where uniqueid = '"+str(r[5])+"'")
  140.  
  141.     cur_update.close()
  142.     cur.close()
  143.     conn.close()
  144.     return retlist
  145.  
  146.  
  147. def check_extension_cdr(uniqueid):
  148.  
  149.     retlist =[]
  150.  
  151.     conn = pymysql.connect(host=HOST, port=PORT,user=USER,passwd=PASSWD,db=DB)
  152.     cur = conn.cursor()
  153.     cdr_tables = "cdro_"+str(time.strftime("%Y_%-m_%-d",time.localtime()))
  154.     cur.execute("select 1 from information_schema.TABLES where table_name='"+cdr_tables+"'")
  155.  
  156.     if cur.rowcount > 0 :
  157.  
  158.         cur.execute("select src, dst, amaflags, billsec,disposition,uniqueid,userfield,calldate,hangup_src from asteriskcdrdb."+cdr_tables+" where uniqueid = '"+uniqueid+"'")
  159.         for r in cur:
  160.             row ={'src': str_number_strip_check(str(r[0])),'dst' : str_number_strip_check(str(r[1])),'amaflags': str(r[2]),'billsec': str(r[3]),'disposition': str(r[4]),'uniqueid': str(r[5]),'userfield': str(r[6]),'calldate': str(r[7]),'hangup_src': str(r[8])}
  161.             retlist.append(row)
  162.  
  163.     cur.close()
  164.     conn.close()
  165.     return retlist
  166.  
  167.  
  168. def get_device_by_extension(extension):
  169.  
  170.     conn = pymysql.connect(host=HOST, port=PORT,user=USER,passwd=PASSWD,db=DB)
  171.     cur = conn.cursor()
  172.     cur.execute("select device from `asterisk`.`device_login` where extension = '"+extension+"'  limit 1 ")
  173.     device = ""
  174.     for r in cur:
  175.         device = 'MIDEA'+str(r[0])
  176.     cur.close()
  177.     conn.close()
  178.  
  179.     return device
  180.  
  181. #update set heart data
  182. def update_set_heart(extension):
  183.  
  184.     conn = pymysql.connect(host=HOST, port=PORT,user=USER,passwd=PASSWD,db=DB)
  185.     cur = conn.cursor()
  186.     cur.execute("UPDATE asterisk.device_login set heart_time = UNIX_TIMESTAMP(NOW()) where extension = '" + extension +"'")
  187.     cur.close()
  188.     conn.close()
  189.  
  190.     return ""
  191.  
  192.  
  193. def get_extension_pop_callin(extension):
  194.  
  195.     conn = pymysql.connect(host=HOST, port=PORT,user=USER,passwd=PASSWD,db=DB)
  196.     cur = conn.cursor()
  197.     cur.execute("select activation, calla as src , callb as dst, uid, Stats, action, pjid from asteriskcdrdb.pop where  callb='"+extension+"' limit 1 ")
  198.     row = ""
  199.     for r in cur:
  200.         device = get_device_by_extension(str(r[2]));
  201.         row ={'Event':'CALLIN','Time':str(r[0]),'CallId' : str_number_strip_check(str(r[1])), 'StaffId': str(r[2]), 'CallSession': str(r[3]), 'Stats': str(r[4]),'action': str(r[5]),'action': str(r[6]),'TerminalId':device}
  202.         cur.execute("DELETE from asteriskcdrdb.pop where uid = '"+str(r[3])+"'")
  203.  
  204.     cur.execute("update asterisk.users set heart_times =NOW() where extension = '"+extension+"'")
  205.  
  206.     cur.close()
  207.     conn.close()
  208.     return row
  209.  
  210. def get_extension_pop_callout(extension):
  211.  
  212.     conn = pymysql.connect(host=HOST, port=PORT,user=USER,passwd=PASSWD,db=DB)
  213.     cur = conn.cursor()
  214.     cur.execute("select activation, calla as src , callb as dst, uid, Stats, action, pjid from asteriskcdrdb.pop where  calla='"+extension+"' limit 1")
  215.     row = ""
  216.     for r in cur:
  217.         device = get_device_by_extension(str(r[1]))
  218.         row ={'Event':'CALLOUT','Time':str(r[0]),'StaffId' : str(r[1]), 'CallId': str_number_strip_check(str(r[2])), 'CallSession': str(r[3]), 'Stats': str(r[4]),'action': str(r[5]),'action': str(r[6]),'TerminalId':device}
  219.         cur.execute("DELETE from asteriskcdrdb.pop where uid = '"+str(r[3])+"'")
  220.  
  221.     cur.close()
  222.     conn.close()
  223.     return row
  224.  
  225. #get http request
  226. def http_reques_uncallcc(url):
  227.     req_header = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11',
  228.              'Accept':'text/html;q=0.9,*/*;q=0.8',
  229.              'Accept-Charset':'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
  230.              'Accept-Encoding':'gzip',
  231.              'Connection':'close',
  232.              'Referer':None
  233.              }
  234.     req_timeout = 3
  235.     req = urllib2.Request(url,None,req_header)
  236.     resp = urllib2.urlopen(req,None,req_timeout)
  237.     html = resp.read()
  238.     return html
  239.  
  240. def parse_data(msg):
  241.     code_length = ord(msg[1]) & 127
  242.  
  243.     if code_length == 126:
  244.         masks = msg[4:8]
  245.         data = msg[8:]
  246.     elif code_length == 127:
  247.         masks = msg[10:14]
  248.         data = msg[14:]
  249.     else:
  250.         masks = msg[2:6]
  251.         data = msg[6:]
  252.  
  253.     i = 0
  254.     raw_str = ''
  255.  
  256.     for d in data:
  257.         raw_str += chr(ord(d) ^ ord(masks[i%4]))
  258.         i += 1
  259.     return raw_str  
  260.         
  261. def sendMessage(message):
  262.     global connectionlist
  263.     for connection in connectionlist.values():
  264.         back_str = []
  265.         back_str.append('\x81')
  266.         data_length = len(message)
  267.     
  268.         if data_length <= 125:
  269.             back_str.append(chr(data_length))
  270.         else:
  271.             back_str.append(chr(126))
  272.             back_str.append(chr(data_length >> 8))
  273.             back_str.append(chr(data_length & 0xFF))
  274.     
  275.         back_str = "".join(back_str) + message
  276.         write_log(u'send message:' +  message)
  277.         connection.send(back_str)
  278.  
  279. def sendMessageIndex(message, index):
  280.  
  281.     try:
  282.  
  283.         global connectionlist
  284.  
  285.         back_str = []
  286.         back_str.append('\x81')
  287.         data_length = len(message)
  288.  
  289.         if data_length <= 125:
  290.             back_str.append(chr(data_length))
  291.         else:
  292.             back_str.append(chr(126))
  293.             back_str.append(chr(data_length >> 8))
  294.             back_str.append(chr(data_length & 0xFF))
  295.  
  296.         back_str = "".join(back_str) + message
  297.         write_log(u'send message:' +  message)
  298.  
  299.         connectionlist['connection'+str(index)].send(back_str)
  300.  
  301.     except (ZeroDivisionError,Exception) as e:
  302.         del webclasslist[index]
  303.         connectionlist['connection'+str(index)].is_login = 0
  304.         deleteconnection(str(index))
  305.         connectionlist['connection'+str(index)].close()
  306.         write_log("EX1------->"+e)
  307.  
  308. def deleteconnection(item):
  309.     global connectionlist
  310.     global webclasslist
  311.     del webclasslist[item]
  312.     del connectionlist['connection'+item]
  313.  
  314. class WebSocket(threading.Thread):
  315.  
  316.     GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"
  317.  
  318.     def __init__(self,conn,index,name,remote, path="/"):
  319.  
  320.         threading.Thread.__init__(self)
  321.         self.conn = conn
  322.         self.index = index
  323.         self.name = name
  324.         self.remote = remote
  325.         self.path = path
  326.         self.buffer = ""
  327.         self.extension = ""
  328.         self.is_login = 0
  329.         self.device =""
  330.         self.status = ""
  331.  
  332.  
  333.     def run(self):
  334.         
  335.         write_log('Uncallcc Web Socket%s Start!' % self.index)
  336.         headers = {}
  337.         self.handshaken = False
  338.  
  339.         while True:
  340.  
  341.             if self.handshaken == False:
  342.                 
  343.                 write_log('Socket%s Start Handshaken with %s!' % (self.index,self.remote))
  344.                 self.buffer += bytes.decode(self.conn.recv(RECV_BUF_SIZE))
  345.                 if self.buffer.find('\r\n\r\n') != -1:
  346.                     header, data = self.buffer.split('\r\n\r\n', 1)
  347.                     for line in header.split("\r\n")[1:]:
  348.                         key, value = line.split(": ", 1)
  349.                         headers[key] = value
  350.  
  351.                     headers["Location"] = ("ws://%s%s" %(headers["Host"], self.path))
  352.                     key = headers['Sec-WebSocket-Key']
  353.                     token = b64encode(hashlib.sha1(str.encode(str(key + self.GUID))).digest())
  354.  
  355.                     handshake="HTTP/1.1 101 Switching Protocols\r\n"\
  356.                         "Upgrade: websocket\r\n"\
  357.                         "Connection: Upgrade\r\n"\
  358.                         "Sec-WebSocket-Accept: "+bytes.decode(token)+"\r\n"\
  359.                         "WebSocket-Origin: "+str(headers["Origin"])+"\r\n"\
  360.                         "WebSocket-Location: "+str(headers["Location"])+"\r\n\r\n"
  361.  
  362.                     self.conn.send(str.encode(str(handshake)))
  363.                     self.handshaken = True
  364.                     write_log('Socket%s Handshaken with %s success!' %(self.index, self.remote)) 
  365.             else:
  366.  
  367.                 try:
  368.  
  369.                     mm=self.conn.recv(RECV_BUF_SIZE)
  370.                     msg_utf8 = parse_data(mm) #utf8
  371.                     msg_unicode = msg_utf8.decode('utf-8', 'ignore') #unicode
  372.                     msg_json_data = json.loads(msg_unicode)
  373.  
  374.                     action = msg_json_data['Event']
  375.  
  376.                     if self.is_login == 0:
  377.  
  378.                         if action!="LOGIN":
  379.  
  380.                             if action == 'LOGOUT': #quit
  381.  
  382.                                 extension = msg_json_data['extension']
  383.                                 paaswd = msg_json_data['paaswd'] 
  384.  
  385.                                 request_url = "http://"+UNCALL_HTTP_HOST+"/phpapi/deviceloout.php?exten="+ extension +"&device="+devices
  386.                                 write_log('-----> %s action LOGOUT : %s ' %(self.index, request_url))
  387.  
  388.                                 request = http_reques_uncallcc(request_url) 
  389.  
  390.                                 if request == "OK":
  391.                                     ret_data = {'Event':'LOGOUT','errorCode':'E0','errorMsg':'SUCCESS'}
  392.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  393.                                 else:
  394.                                     ret_data = {'Event':'LOGOUT','errorCode':'E6','errorMsg':request}
  395.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  396.  
  397.                             else :
  398.                                 ret_data = {'Event':'LOGIN','errorCode':'E2','errorMsg':'NO LOGIN'}
  399.                                 sendMessageIndex(json.dumps(ret_data),self.index)
  400.  
  401.                         else :
  402.  
  403.                             extension = msg_json_data['extension']
  404.                             paaswd = msg_json_data['paaswd'] 
  405.  
  406.                             write_log('----->action start login : %s : %s ' %(self.index, paas))
  407.  
  408.                             if check_extension(extension) > 0 :
  409.  
  410.                                 self.is_login=1
  411.                                 self.extension = extension
  412.                                 ret_data = {'Event':'LOGIN','errorCode':'E0','errorMsg':'SUCCESS'}
  413.                                 sendMessageIndex(json.dumps(ret_data),self.index)
  414.  
  415.                             else :
  416.                                 ret_data = {'Event':'LOGIN','errorCode':'E4','errorMsg':'NO EXTEN'}
  417.                                 sendMessageIndex(json.dumps(ret_data),self.index)
  418.                     else:
  419.  
  420.                         # dial
  421.                         if action != "DIAL" and action != "QUIT" and action != "LOGOUT" and action !="HANGUP" and action != "GETSEATALL" and action !="GETSEAT" and action !="HB" and action !="SETBUSY"  and action !="SETIDLE" and action !="TRANSFERCALL" and action!='CHECK_CDR' and action !="CALLIN" and action != "CALLOUT" :
  422.                             ret_data = {'errorCode':'E3','errorMsg':'NO EVENT'}
  423.                             sendMessageIndex(json.dumps(ret_data),self.index)
  424.  
  425.                         else:
  426.  
  427.                             if action == 'QUIT': #quit
  428.                                 extension = msg_json_data['StaffId']
  429.                                 devices_midea = msg_json_data['TerminalId']
  430.                                 devices = devices_midea[5:]
  431.                                 request_url = "http://"+UNCALL_HTTP_HOST+"/phpapi/deviceloout.php?exten="+self.extension+"&device="+devices
  432.                                 write_log('-----> %s action QUIT : %s ' %(self.index, request_url))
  433.                                 request = http_reques_uncallcc(request_url)
  434.                                 ret_data = {'Event':'QUIT','errorCode':'E0','errorMsg':'SUCCESS'}
  435.                                 sendMessageIndex(json.dumps(ret_data),self.index)
  436.                                 self.is_login=0
  437.                                 deleteconnection(str(self.index))
  438.                                 self.conn.close()
  439.                                 break
  440.  
  441.  
  442.                             if action == 'DIAL': #dial event
  443.                                 request_url = "http://"+UNCALL_HTTP_HOST+"/phpapi/call.php?extension="+self.device+"&phone="+msg_json_data['DTMF']
  444.                                 request = http_reques_uncallcc(request_url)
  445.                                 write_log('-----> %s action DIAL : %s ' %(self.index, request_url))
  446.                                 if request == "OK":
  447.                                     ret_data = {'Event':'DIAL','errorCode':'E0','errorMsg':'SUCCESS'}
  448.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  449.                                 else:
  450.                                     ret_data = {'Event':'DIAL','errorCode':'E5','errorMsg':'FAILED'}
  451.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  452.  
  453.  
  454.                             if action == "HB": #pop event
  455.                                 ret_data = {'Event':'HB','errorCode':'E0','errorMsg':'SUCCESS'}
  456.                                 write_log('-----> %s action HB : %s ' %(self.index, extension))
  457.                                 update_set_heart(extension)
  458.                                 sendMessageIndex(json.dumps(ret_data),self.index)
  459.  
  460.                             if action == "GETSEATALL" : #ALL STATUS
  461.                                 ret_data = {'Event':'GETSEATALL','errorCode':'E0','errorMsg':'SUCCESS','data':get_extension_status_all()}
  462.                                 sendMessageIndex(json.dumps(ret_data),self.index)
  463.  
  464.                             if action == "HANGUP": #HANGUP
  465.                                 request_url = "http://"+UNCALL_HTTP_HOST+"/phpapi/hangup.php?extension="+self.device
  466.                                 request = http_reques_uncallcc(request_url)
  467.                                 write_log('-----> %s action HANGUP : %s ' %(self.index, request_url))
  468.                                 if request == "OK":
  469.                                     ret_data = {'Event':'HANGUP','errorCode':'E0','errorMsg':'SUCCESS'}
  470.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  471.                                 else:
  472.                                     ret_data = {'Event':'HANGUP','errorCode':'E5','errorMsg':'FAILED'}
  473.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  474.  
  475.                             if action == "SETBUSY" : #set busy
  476.  
  477.                                 request_url = "http://"+UNCALL_HTTP_HOST+"/phpapi/setbusy.php?extension="+self.device
  478.                                 request = http_reques_uncallcc(request_url)
  479.                                 write_log('-----> %s action SETBUSY : %s ' %(self.index, request_url))
  480.                                 if request == "OK":
  481.                                     ret_data = {'Event':'SETBUSY','errorCode':'E0','errorMsg':'SUCCESS'}
  482.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  483.                                 else:
  484.                                     ret_data = {'Event':'SETBUSY','errorCode':'E5','errorMsg':'FAILED'}
  485.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  486.  
  487.                             if action == "SETIDLE" : #set idle
  488.                                 request_url = "http://"+UNCALL_HTTP_HOST+"/phpapi/setIdle.php?extension="+self.device
  489.                                 write_log('-----> %s action SETIDLE : %s ' %(self.index, request_url))
  490.                                 request = http_reques_uncallcc(request_url)
  491.                                 if request == "OK":
  492.                                     ret_data = {'Event':'SETIDLE','errorCode':'E0','errorMsg':'SUCCESS'}
  493.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  494.                                 else:
  495.                                     ret_data = {'Event':'SETIDLE','errorCode':'E5','errorMsg':'FAILED'}
  496.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  497.  
  498.                             if action == "TRANSFERCALL" : #transferCall
  499.                                 request_url = "http://"+UNCALL_HTTP_HOST+"/phpapi/transferCall.php?extension="+self.device+"&phone="+msg_json_data['Phone']
  500.                                 write_log('-----> %s action TRANSFERCALL : %s ' %(self.index, request_url))
  501.                                 request = http_reques_uncallcc(request_url)
  502.                                 if request == "OK":
  503.                                     ret_data = {'Event':'TRANSFERCALL','errorCode':'E0','errorMsg':'SUCCESS'}
  504.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  505.                                 else:
  506.                                     ret_data = {'Event':'TRANSFERCALL','errorCode':'E5','errorMsg':'FAILED'}
  507.                                     sendMessageIndex(json.dumps(ret_data),self.index)
  508.  
  509.                             if action == "CHECK_CDR":
  510.                                 uniquid = msg_json_data['Uniquid']
  511.                                 cdr_list = check_extension_cdr(uniquid)
  512.                                 ret_data = {'Event':'CHECK_CDR','errorCode':'E0','errorMsg':'SUCCESS','data':cdr_list}
  513.                                 sendMessageIndex(json.dumps(ret_data),self.index)
  514.  
  515.                             if action == "CALLIN":
  516.                                 ret_data = {'Event':'CALLIN','errorCode':'E0','errorMsg':'SUCCESS'}
  517.                                 sendMessageIndex(json.dumps(ret_data),self.index)
  518.  
  519.                             if action == "LOGOUT":
  520.                                 request_url = "http://"+UNCALL_HTTP_HOST+"/phpapi/deviceloout.php?exten="+self.extension+"&device="+self.device
  521.                                 request = http_reques_uncallcc(request_url)
  522.                                 write_log('-----> %s action LOGOUT : %s ' %(self.index, request_url))
  523.                                 ret_data = {'Event':'CALLOUT','errorCode':'E0','errorMsg':'SUCCESS'}
  524.                                 sendMessageIndex(json.dumps(ret_data),self.index)
  525.                                 self.is_login=0
  526.                                 deleteconnection(str(self.index))
  527.                                 self.conn.close()
  528.                                 break
  529.  
  530.                 except (ZeroDivisionError,Exception) as e:
  531.                         ret_data = {'errorCode':'E1','errorMsg':'REQUEST ERROR'}
  532.                         self.is_login=0
  533.                         deleteconnection(str(self.index))
  534.                         self.conn.close()
  535.                         write_log("EX02---> "+str(self.index)+" :"+str(e))
  536.                         break
  537.  
  538.             self.buffer = ""
  539.  
  540.  
  541. class WebSocketServer(object):
  542.  
  543.     def __init__(self):
  544.         self.socket = None
  545.  
  546.     def begin(self):
  547.  
  548.         write_log('Uncallcc WebSocketServer Start!') 
  549.  
  550.         self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  551.         self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
  552.         self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, SEND_BUF_SIZE)
  553.         self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, RECV_BUF_SIZE)
  554.         self.socket.bind((LISTEN_IP,LISTEN_PORT))
  555.         self.socket.listen(100)
  556.  
  557.         global connectionlist
  558.         global webclasslist
  559.  
  560.         i=0
  561.         while True:
  562.             connection, address = self.socket.accept()
  563.             username=address[0]     
  564.             newSocket = WebSocket(connection,i,username,address)
  565.             newSocket.start()
  566.             webclasslist[i]= newSocket
  567.             connectionlist['connection'+str(i)]=connection
  568.             write_log('add connection'+str(i))
  569.             i = i + 1
  570.  
  571.  
  572. if __name__ == "__main__":
  573.     t = threading.Thread(target=data_check)
  574.     t.setDaemon(True)
  575.     t.start()
  576.     server = WebSocketServer()
  577.     server.begin()



三、HTML websocket 测试


  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4.     <title>WebSocket</title>
  5.     <style>
  6.         html, body {
  7.             font: normal 0.9em arial, helvetica;
  8.         }
  9.  
  10.         #log {
  11.             width: 800px;
  12.             height: 400px;
  13.             border: 1px solid #7F9DB9;
  14.             overflow: auto;
  15.         }
  16.  
  17.         #msg {
  18.             width: 800px;
  19.         }
  20.     </style>
  21.  
  22.     <script>
  23.  
  24.         var socket;
  25.         
  26.         function init() {
  27.             var host = "ws://120.177.122.25:6899/";
  28.             try {
  29.                 socket = new WebSocket(host);
  30.                 socket.onopen = function (msg) {
  31.                     log('Connected');
  32.                 };
  33.                 socket.onmessage = function (msg) {
  34.                     
  35.                     log(msg.data);
  36.  
  37.                     if(msg.data=="SUCCESS"){//连接成功
  38.  
  39.                     }
  40.  
  41.                     if(msg.data.indexOf("errorCode")){//有事件交互
  42.                         var json_data = JSON.parse(msg.data); 
  43.                         console.log(json_data['errorCode']); 
  44.                         if(json_data['errorCode']=="E0"){
  45.                             if(json_data['Event']=="LOGIN"){//
  46.                                 console.log('SUCCESS LOGIN');
  47.                                 send_hearbeat();
  48.                             }
  49.                         }
  50.                     }
  51.  
  52.                 };
  53.                 socket.onclose = function (msg) {
  54.                     log("Lose Connection!");
  55.                 };
  56.             }
  57.             catch (ex) {
  58.                 log(ex);
  59.             }
  60.             $("msg").focus();
  61.         }
  62.  
  63.         function send_hearbeat()
  64.         { 
  65.             socket.send("{\"Event\":\"HB\",\"Exten\":\"801\"}");
  66.             setTimeout("send_hearbeat();", 30000);
  67.         }
  68.         
  69.  
  70.         function send() {
  71.             var txt, msg;
  72.             txt = $("msg");
  73.             msg = txt.value;
  74.             if (!msg) {
  75.                 alert("Message can not be empty");
  76.                 return;
  77.             }
  78.             txt.value = "";
  79.             txt.focus();
  80.             try {
  81.                 socket.send(msg);
  82.             } catch (ex) {
  83.                 log(ex);
  84.             }
  85.         }
  86.  
  87.         window.onbeforeunload = function () {
  88.             try {
  89.                 socket.send('quit');
  90.                 socket.close();
  91.                 socket = null;
  92.             }
  93.             catch (ex) {
  94.                 log(ex);
  95.             }
  96.         };
  97.  
  98.  
  99.         function $(id) {
  100.             return document.getElementById(id);
  101.         }
  102.         
  103.         function log(msg) {
  104.             $("log").innerHTML += "<br>" + msg;
  105.         }
  106.  
  107.         function onkey(event) {
  108.             if (event.keyCode == 13) {
  109.                 send();
  110.             }
  111.         }
  112.     </script>
  113.  
  114. </head>
  115.  
  116.  
  117. <body onload="init()">
  118. <h3>Uncallcc WebSocket Demo</h3>
  119. <br><br>
  120.  
  121. <div id="log"></div><br><br>
  122. <input id="msg" type="textbox" onkeypress="onkey(event)"/>
  123. <br><br>
  124. <button onclick="send()">Send</button>
  125. </body>
  126.  
  127. </html>