gpt4 book ai didi

ios - 如何在 RPGLE 中构建 APNS 通知?

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:16:30 26 4
gpt4 key购买 nike

下午好,

我正在尝试创建一个连接到 Apple 推送通知服务 (APNS) 并发送推送通知的套接字程序。

我想知道是否有人可以帮助我实际编写 APNS 通知。

下面您可以看到我使用 Scott Klement 的套接字编程教程帮助我完成的程序。

可能与所有这些相关的代码在注释中标记为“APNS 通知格式开始”、“初始化”和“向 APNS 发送消息”,尽管我包含了整个程序以供引用。

我已阅读 Apple 网站上的供应商要求 Provider Requirements但我仍然无法让一切正常工作。

我的程序编译并且当我调试它/运行我通过建立实际连接的步骤时,所以我“认为”这部分没问题。

我希望在 item3 数据结构中的变量 errid 中从 Apple 取回错误标识符。 Apple 在提供商要求中声明,如果出现错误,他们将返回一个状态代码,但该特定变量仍为 1077952576

还有很多事情我不确定

1) 我已获得作为 Base64 字符串的设备 token 。该字符串的长度为 40 个奇数字符,但据我了解,Apple 声明设备 token 长度应为 32 个字节。在 RPGLE 中,1 个字符不代表 1 个字节吗?如果是这样,那么我不能只将我的变量标记声明为

D   token                       32a

因为它会被切断?

2) 当返回到我的变量 errid 中从 Apple 接收到正确的错误标识符时,有人能告诉我我做错了什么吗?

任何帮助将不胜感激

H DFTACTGRP(*NO) BNDDIR('QC2LE')
D/copy socket_h
D/copy gskssl_h

*==============================================================*
* APNS Notification Format Begin
*==============================================================*
D request s 1000a varying

D framehdr ds
D command 3I 0 inz(2)
D framelen 10I 0

D framedta s 500a varying

D item1 ds
D itemid1 3I 0 inz(1)
D itemlen1 5I 0 inz(%size(token))
D token 64a

D item2 ds
D itemid2 3I 0 inz(2)
D itemlen2 5I 0
D payload 100a varying

D item3 ds
D itemid3 3I 0 inz(3)
D itemlen3 5I 0 inz(%size(errid))
D errid 10I 0

D item4 ds
D itemid4 3I 0 inz(4)
D itemlen4 5I 0 inz(%size(expire))
D expire 10I 0 inz(0)

D item5 ds
D itemid5 3I 0 inz(5)
D itemlen5 5I 0 inz(%size(priority))
D priority 10I 0 inz(10)

*==============================================================*
* APNS Notification Format End
*==============================================================*

D gsk_strerror PR * extproc('gsk_strerror')
D gsk_ret_value 10I 0 value

D CreateEnv PR like(gsk_handle)

D ConnSock PR 10I 0
d host 256A const
D port 10I 0 value

D UpgradeSock PR like(gsk_handle)
D SslEnv like(gsk_handle) value
D sock 10I 0 value

D CloseSsl PR
D Handle like(gsk_handle) value

D CloseSslEnv PR
D SslEnv like(gsk_handle) value

D ReportError PR

D EscapeMsg PR

D errMsg s 80A varying
D CRLF c x'0d25'
D env s like(gsk_handle)
D s s 10I 0
D connto ds likeds(sockaddr_in)
D SslSock s like(gsk_handle)
D cmd s 400A
D len s 10I 0
D bytesSent s 10I 0
D Reply s 1000A
D bytesRead s 10I 0
D left s 10I 0
D buf s *
D received s 10I 0
D dataPos s 10I 0
D wait s 1A
D rc s 10I 0

/free

// Initialize
token = 'MyDevToken';
payload = '{"aps":{"alert":"You have mail"}}';
itemlen1 = %len(payload);
framedta = item1 + item2 + item3 + item4 + item5;
framelen = %len(framedta);

request = framehdr + framedta;

// Create SSL Environment

env = CreateEnv();
If (env = *NULL);
EscapeMsg();
Endif;

// Connect a socket to an SSL server (using normal socket calls)
// NOTE: Sandbox is the development environment

s = ConnSock('gateway.sandbox.push.apple.com': 2195);

// Upgrade the socket to SSL

SSLSock = UpgradeSock(env: s);
If (SSLSock = *NULL);
EscapeMsg();
Endif;

// **** Formulate message to APNS ******
len = %len(%trimr(request));

callp gsk_secure_soc_write(SSLSock
: %addr(request)
: len
: bytesSent);



// Close everything and end the program

CloseSsl(SslSock);
CloseSslEnv(Env);

*inlr = *on;

/end-free


*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* CreateEnv(): Create an SSL environment for client sockets
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P CreateEnv B
D CreateEnv PI like(gsk_handle)
D rc s 10I 0
D SslEnv s like(Gsk_handle)

/free

// Create an SSL environment with default values:

rc = gsk_environment_open(SslEnv);
If (rc <> GSK_OK);
errMsg = %str(gsk_strerror(rc));
return *NULL;
Endif;

// Instruct environment to use the *SYSTEM certificate store

rc = gsk_attribute_set_buffer( SslEnv
: GSK_OS400_APPLICATION_ID
: 'SUMITOMO_APNS_PUSH'
:0 );
If (rc<>GSK_OK);
errMsg = %str(gsk_strerror(rc));
gsk_environment_close( SslEnv );
return *NULL;
Endif;

//Tell the environment that this is a client connection
rc = gsk_attribute_set_enum( SslEnv
: GSK_SESSION_TYPE
: GSK_CLIENT_SESSION );

If (rc <> GSK_OK);
errMsg = %str(gsk_strerror(rc));
gsk_environment_close( SslEnv );
return *NULL;
Endif;

// Activate the new environment

rc = gsk_environment_init( SslEnv );
If (rc <> GSK_OK);
errMsg = %str(gsk_strerror(rc));
gsk_environment_close( SslEnv );
return *NULL;
Endif;

return SslEnv;

/end-free
P E

*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* ConnSock(): Create a TCP Socket and connect to a host
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P ConnSock B
D ConnSock PI 10I 0
d host 256A const
D port 10I 0 value
D s s 10I 0
D addr s 10U 0

/free

// look up host

addr = inet_addr(%trim(host));
If (addr = INADDR_NONE);
p_hostent = gethostbyname(%trim(host));
If (p_hostent = *NULL);
errMsg = 'Host not found!';
EscapeMsg();
Endif;
addr = h_addr;
Endif;

// Create a socket

s = socket(AF_INET: SOCK_STREAM: IPPROTO_IP);
If (s < 0);
ReportError();
Endif;

// connect to the host

connto = *ALLx'00';
connto.sin_family = AF_INET;
connto.sin_addr = addr;
connto.sin_port = port;

If (connect(s: %addr(Connto): %size(connto)) = -1);
callp close(S);
ReportError();
Endif;

return s;
/end-free
P E

*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* UpgradeSock(): Upgrade a socket to use SSL
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P UpgradeSock B
D UpgradeSock PI like(gsk_handle)
D SslEnv like(gsk_handle) value
D sock 10I 0 value
D Handle s like(Gsk_handle)

/free

rc = gsk_secure_soc_open(SslEnv: Handle);
If (rc <> GSK_OK);
errMsg = %str(gsk_strerror(rc));
return *NULL;
Endif;

rc = gsk_attribute_set_numeric_value(Handle
: GSK_HANDSHAKE_TIMEOUT
: 30 );

If (rc <> GSK_OK);
errMsg = %str(gsk_strerror(rc));
gsk_secure_soc_close(Handle);
return *NULL;
Endif;

rc = gsk_secure_soc_init( Handle );
If (rc <> GSK_OK);
errMsg = %str(gsk_strerror(rc));
gsk_secure_soc_close(Handle);
return *NULL;
Endif;

return Handle;
/end-free
P E

*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* CloseSsl(): Close an SSL socket
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P CloseSsl B
D CloseSsl PI
D Handle like(gsk_handle) value
/free
gsk_secure_Soc_close( handle);
/end-free
P E

*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* CloseSslEnv(): Close SSL Environment
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P CloseSslEnv B
D CloseSslEnv PI
D SslEnv like(gsk_handle) value
/free
gsk_environment_close( SslEnv );
/end-free
P E

*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* EscapeMsg(): Send an escape message w/reason for SSL failure
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P EscapeMsg B
D EscapeMsg PI
D SndPgmMsg PR ExtPgm('QMHSNDPM')
D MessageID 7A Const
D QualMsgF 20A Const
D MsgData 256A Const
D MsgDtaLen 10I 0 Const
D MsgType 10A Const
D CallStkEnt 10A Const
D CallStkCnt 10I 0 Const
D MessageKey 4A
D ErrorCode 1A

D ErrorCode DS
D BytesProv 10I 0 inz(0)
D BytesAvail 10I 0 inz(0)

D wwTheKey S 4A

/free
SndPgmMsg( 'CPF9897'
: 'QCPFMSG *LIBL'
: errMsg
: %len(%trimr(errMsg))
: '*ESCAPE'
: '*CTLBDY'
: 1
: wwTheKey
: ErrorCode );
/end-free
P E

*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* ReportError(): Send an escape message explaining any errors
* that occurred.
*
* This function requires binding directory QC2LE in order
* to access the __errno() function.
*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P ReportError B
D ReportError PI

D get_errno PR * ExtProc('__errno')
D ptrToErrno s *
D errno s 10I 0 based(ptrToErrno)

D QMHSNDPM PR ExtPgm('QMHSNDPM')
D MessageID 7A Const
D QualMsgF 20A Const
D MsgData 1A Const
D MsgDtaLen 10I 0 Const
D MsgType 10A Const
D CallStkEnt 10A Const
D CallStkCnt 10I 0 Const
D MessageKey 4A
D ErrorCode 8192A options(*varsize)

D ErrorCode DS qualified
D BytesProv 1 4I 0 inz(0)
D BytesAvail 5 8I 0 inz(0)

D MsgKey S 4A
D MsgID s 7A

/free

ptrToErrno = get_errno();
MsgID = 'CPE' + %char(errno);

QMHSNDPM( MsgID
: 'QCPFMSG *LIBL'
: ' '
: 0
: '*ESCAPE'
: '*PGMBDY'
: 1
: MsgKey
: ErrorCode );
/end-free
P E

最佳答案

这还差得远,您使用的是字符而不是二进制数据。

cmd = '2' + 3 + 1 + 64 + 'x' + 2 + 50 + '{"aps":{"alert":"You have mail"}} +
3 + 3 + '001'

这应该更近;但它不在我的脑海中,完全未经测试......

 d request         s           1000a   varying

d frame_hdr ds
d cmd 1a inz(x'02')
d frame_len 10i 0

d frame_data s 500a varying

d device_item ds
d 1a inz(x'01')
d 5i 0 inz(%size(device_item))
d token 32a

d item_hdr ds
d id 1a inz(x'02')
d item_len 5i 0


d item_data s 100a varying

item_data = '{"aps":{"alert":"You have mail"}}';
item_len = %len(item_data);

token = myDevID;
frame_data = device_item + item_hdr + item_data;
frame_len = %len(frame_data);

request = frame_hdr + frame_data;

callp gsk_secure_soc_write(SSLSock
: %addr(request:*DATA)
: %len(request)
: bytesSent);

我以前没有在 IBM i 上做过原始套接字,您可能需要将 EBCDIC 转换为 ASCII。我不认为你需要担心小端与大端。

RPG 可能不是最好的选择,鉴于 Java PNS 等项目的存在,Java 可能是更好的选择

Stackoverflow 没有大量的 RPG/IBM i 流量。您可能会在以下方面得到更好的回应:

关于ios - 如何在 RPGLE 中构建 APNS 通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29401333/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com