当前位置: 代码迷 >> Web前端 >> APLLE推送服务器的筹建
  详细解决方案

APLLE推送服务器的筹建

热度:285   发布时间:2012-09-04 14:19:30.0
APLLE推送服务器的搭建

现在APLLE的应用越来越广泛,对于开发者来说APPLE应用开发也多少会接触到,笔者也通过这周APLLE推送服务器的搭建慢慢有所体会

笔者是使用python2.5+django1.4+apache2.2+mysql4.0所搭建的服务器,网页设计部分用的DREAMWEAVER,python的一些小插件更新的太慢所以不得不用2.5版本了,

首先应该对PUSH服务器有所了解,建议参考以下文章:

http://www.cnblogs.com/menghe/archive/2012/02/20/2359278.html   证书的创建

http://hb.qq.com/a/20111128/000536.htm      iOS开发如何实现消息推送机制

django和mysql的配置部分就不详细介绍了,可参考我另一边博文:http://blog.csdn.net/wulei202/article/details/7667473

准备工作做完后即可着手搭建服务器了

 

首先应在winxp 环境为python2.5加上ssl库:

该过程中可能有些步骤可以发生变动

1 在http://pypi.python.org/pypi/ssl/下载的 ssl-1.15.tat.gz 只能下载到source包需要自己编译,解压该文件目录为SSL-1.15

2 下载mingw32 在http://sourceforge.net/projects/mingw/files/点击mingw-get-inst-20110530.exe

3 下载Oenssl  在http://gnuwin32.sourceforge.net/packages/openssl.htm选择Developer files

4 下载libgw32c 在http://gnuwin32.sourceforge.net/packages/libgw32c.htm选择Developer files

5这是个在线安装程序、后面的日期灵活变动。我安装时全选安装所有功能、貌似选择g++编译器和mingw make环境即可

   然后新建批处理abc.bat内容如下:

set PATH=%PATH%;D:\MinGW\bin

set LIBRARY_PATH=D:\MinGW\lib

set C_INCLUDE_PATH=D:\MinGW\include

在MinGW下新建文件夹abc解压Oenssl和libgw32c到D:\MinGW\abc,后解压的哪个若提示是否替换原有的文件、点全部。

abc下的目录为abc\include,abc\lib,abc\manifest

在SSL-1.15目录下修改setup.py搜索gnuwin32_dir 将其改为

gnuwin32_dir = os.environ.get("GNUWIN32_DIR", r"D:\MinGW\abc")

在命令提示符中切换到SSL-1.15目录输入

python setup.py build -c mingw32 install即可完成PYTHONT 2.5的ssl库添加

 

6 测试SSL

在命令提示符中输入python打开python的CLI

然后输入import ssl若提示No module named _ssl2

进入C:\Python25\Lib\site-packages\SSL,删除__init__.pyc

然后再在命令提示符中切换到SSL-1.15目录输入

python setup.py build -c mingw32 install

重新再测试应该会不再报错

 

笔者在sourceforge上下载时出了问题,居然打不开(原因我想都懂的,不得不抱怨下国内的技术环境了怪不得赶不上国外)得亏公司有VPN才得以解决问题

完成ssl库导入之后就要导入json库了,这个在网上搜下就有

ssl及json库导入完成之后就剩下APNs with python 了

APNs 可以参考 http://mobiforge.com/developing/story/programming-apple-push-notification-services

代码可参考:

import socket, ssl, json

deviceToken = "11111111 22222222 aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff" #换成你的deviceToken

  • data = json.dumps({"aps":{"alert":"Hello!"}})

    ssl_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), certfile="certDist.pem") #换成你上面生成的pem

    ssl_sock.connect(("gateway.push.apple.com", 2195)) #测试版本用gateway.sandbox.push.apple.com

  • data = data.decode('gbk').encode('utf-8') #因为你发送的数据有可能是中文,故而需要转换

    ssl_sock.write(chr(0)+chr(0)+chr(32)+deviceToken.replace(' ','').decode('hex')+chr(0)+chr(len(data))+data)

    ssl_sock.close()

    如果运行正常就能在发布版本把消息发给客户端了

    除了发送消息我们应该还有个注册页面来得到令牌ID号

    python代码部分:

    # encoding: utf-8

    import binascii,socket
    import ctypes
    from MySQLdb.constants.CLIENT import SSL
    import ssl,json
    from encodings import hex_codec
    from django.http import HttpResponseRedirect
    from django.http import HttpResponse
    from ssl._ssl2 import *
    from iospushapp.models import *
    from django.shortcuts import render_to_response
    def iospost(request):
        TextOut = request.POST.get('textfield1', None)
        TextPush = unicode(TextOut)#变为unicode版字符
        TextPush = TextPush.replace(' ','')
        TextPush = TextPush.replace('\r\n','')
            if TextPush:
            if len(TextPush.decode('gbk').encode('utf-8')) > 255:
                return render_to_response('iospush.html', {'result':'发送字符数超出!'})
            else:
                nId = iospushId.objects.count()
                strFull = 'id='
                iRet = 0
                iCount = 0
                mode = iospushId.objects.all()
                #mode.iterator()
                while iCount < nId:
                    #strMode = iospushId.objects.get(id=iCount+1)
                    strMode = mode[iCount]
                    deviceToken = str(strMode.PushId)
                    #deviceToken.decode('gbk').encode('utf-8')
                    ibadge = strMode.PushNum + 1
                    #data = json.dumps({"aps":{"alert":TextPush}})
                    data = json.write({"aps":{"alert":TextPush,"badge":ibadge,"sound":"default"}})
                    ssl_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM), certfile="yftechpushck_unencrypted.pem")
                    #ssl_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM),ca_certs="yftechpushck.pem",cert_reqs=ssl.CERT_REQUIRED)
                    #ssl_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM),certfile='cer.pem',keyfile='key.pem',\
                     #   ssl_version = PROTOCOL_SSLv23, ca_certs="yftechpushck.pem",cert_reqs=ssl.CERT_REQUIRED,\
                      #   do_handshake_on_connect = False)
                    ssl_sock.connect(("gateway.sandbox.push.apple.com", 2195)) #测试版本用gateway.sandbox.push.apple.com
                    data = data.decode('gbk').encode('utf-8')
                    strSend = chr(0)+chr(0)+chr(32)+deviceToken.replace(' ','').decode('hex')+chr(0)+chr(len(data))+data
                    nNum = ssl_sock.write(strSend)

                    if nNum == len(strSend):
                        strMode.PushNum+=1
                        strMode.save()
                    else:
                        strFull+=unicode(strMode.id) +';'
                        iRet = 1
                    ssl_sock.close()
                    iCount+=1
                    #str =  TextPush + binascii.a2b_hex('967360565f') + strID.replace(' ','').decode("hex")
                #str = str.encode('utf-8')
                if 0 == iRet:
                    return render_to_response('iospush.html', {'result':'发送成功','textare':''})#,'textare':str
                else:
                    strFull+=u'发送失败!'
                    return render_to_response('iospush.html', {'result':strFull ,'textare':''})#,'textare':str
        else:
            return render_to_response('iospush.html', {'result':'发送内容不得为空!'})

    def initpost(request):
        return render_to_response('iospush.html',{'result':'请输入发送字符(小于85)'})

    网页部分:

    <form method="post" action="/loginid/">
      <p class="STYLE1" style="text-align:center">&nbsp;</p>
      <p class="STYLE1" style="text-align:center">&nbsp;</p>
      <p class="STYLE1" style="text-align:center">&nbsp;</p>
      <p class="STYLE1" style="text-align:center">IOS令牌登记</p>
      <p class="STYLE1" style="text-align:center">
        <input name="textfieldlogin" type="text" size="74" maxlength="100" height="20">
      </p>
      <p class="STYLE1" style="text-align:center">&nbsp;</p>
      <p class="STYLE1" style="text-align:center">
        <input type="submit" name="Submit" value="提交" width="30" height="66">
      </p>
      <p class="STYLE1" style="text-align:center">&nbsp;</p>
      <p class="STYLE1" style="text-align:center">{{result}}</p>
      <p>&nbsp;</p>
    </form>

    点击提交即可保存令牌ID

  •   相关解决方案