動態Cgi 傳值後端(三)

By
Advertisement
動態Cgi 傳值後端(一)動態Cgi 傳值後端(二)的方法有一個傳值長度的限制, 
因此當有需要批次處理的資料要送往後端時, 這種方法的效能就會變得非常差.
並且如果後端回傳值是複數多筆的也不適合透過這種方法處理.

這篇的方法是後端回傳資料時將資料寫入file, 再由前端去讀file已取得多筆的資料.

QryUserList(qry, repfile)
st_IPv6Get              *qry;
char                    *repfile;
{
        int     offset;
        char    subfunction[MAX_FUNCTION_LEN+1];
        offset = 0;
        request.reqlen = MIN_REQ_LEN + MAX_FUNCTION_LEN + sizeof(st_IPv6Get);
        memcpy(&(request.databuf[offset]), "quserlist", MAX_FUNCTION_LEN);
        offset += MAX_FUNCTION_LEN;
        memcpy(&(request.databuf[offset]), qry, sizeof(st_IPv6Get));
        offset += sizeof(st_IPv6Get);

        if (do_request_large_aps(ZUserNameQuery) < 0)
                return(UNKNOW_NET_ERROR);
        if (respond.value == SUCCESS)
                strcpy(repfile, &(respond.databuf[0]));

        return(respond.value);
}

與之前的方法不同的地方在於接收資料時是要讀取repfille.
do_request_large_aps設定暫存檔
在連線的deamon的include/protocols.h中增加此連線的define
#define ZUserNameQuery                  531
do_request_large_aps(opcode)
int     opcode;
{
        int     count;
        int     st;
        char    filename[32], *strptr;

        request.opcode = opcode ;

        if (dbsid <= 0)
                do_tcpopen_aps();

        if ((st = TcpSend(dbsid, (char *) &request, request.reqlen)) !=
                                request.reqlen) {
                TcpClose(dbsid);
                return(-1);
        }
        if ((strptr=(char *)getenv("CGITMP"))!= NULL)
                sprintf(filename, "%s/%03d.cgi", strptr, ((int)getpid() % 1000));
        else
                sprintf(filename, "/tmp/%03d.cgi", (getpid() % 1000));

        if (TcpRecvFile(dbsid, &respond, filename) != 0)
                return(UNKNOW_NET_ERROR);
        strcpy(respond.databuf, filename);

        return(0);
}

../lib/common/tcputil.c
TcpRecvFile(connid, respond, filename)
int                     connid;
struct dbs_respond      *respond;
char                    *filename;
{
        int     totlen, count, len, rtnlen;
        char    buf[BUFSIZ+1];
        int     fd;

        if ((len=OneRecv(connid, respond, MIN_REP_LEN)) != MIN_REP_LEN) {
                return(-1);
        }

        if ((fd = open(filename, O_RDWR|O_CREAT, 0666)) < 0)
                return(-2);

        totlen = respond->replen - MIN_REP_LEN;
        while (totlen > 0) {
                len = (totlen > BUFSIZ) ? BUFSIZ : totlen;
                if ((rtnlen = OneRecv(connid, buf, len)) < 0 ) {
                        close(fd);
                        return(-1);
                }
                totlen -= rtnlen;
                if (write(fd, buf, len) != len) {
                        close(fd);
                        return(-1);
                }
        }
        close(fd);
        return(0);
}

../mklib/funspcA.f
需注意的是, 在用傳Buffer至後端的方式時, struct _DBService 的起始設定為"0"; 若為file則應設為"0x0F".
#ifndef _funspcA_
#define _funspcA_

extern  int     IP_do_ZUserNameQuery(struct dbs_request *, struct dbs_respond *);
extern  int     IP_do_IPStat(struct dbs_request *, struct dbs_respond *);

struct _DBService IP_DBServiceA[] =
{
        { "IPStat", PIPStat, IP_do_IPStat, 1, MAX_ACCESS,0},
        { "ZUserNameQuery", ZUserNameQuery, IP_do_ZUserNameQuery, 0x0F, MAX_ACCESS,0},
        NULL
}

../mklib/ServiceFunc.c
struct _DBService *
GetFunction(opcode)
int     opcode;
{
        int     fidx;
        int     SearchGo;
        struct _DBService * fun;

        SearchGo = TRUE;

        if(SearchGo == TRUE)
        {
                for (fidx=0;fidx < sizeof(IP_DBServiceA)/sizeof(struct _DBService); fidx++) {
                        if (opcode == IP_DBServiceA[fidx].opcode) {
                                fun = (struct _DBService *) &(IP_DBServiceA[fidx]);
                                SearchGo = FALSE;
                                break;
                        }
                }
        }
        return(fun);

}

../mklib/..pc
IP_do_ZUserNameQuery(in, out)
struct dbs_request *in;
struct dbs_respond *out;
{

        char            subfun[MAX_FUNCTION_LEN+1];
        char            buff[8192];
        int             fd;
        int             reclen;
        int             item;
        int             start;
        int             offset;
        st_IPv6Get      qry[1024];
        offset = 0;
        reclen = 0;

        memcpy(&subfun, &(in->databuf[offset]), MAX_FUNCTION_LEN);
        offset += MAX_FUNCTION_LEN;
        if (!strcmp(subfun, "quserlist"))
        {
                memcpy(&qry, &(in->databuf[offset]) , sizeof(st_IPv6Get));
                offset += sizeof(st_IPv6Get);
                fd = initlarge(out->databuf);
                out->value = DBQryUserName(&qry, fd, &reclen);
                out->replen = MIN_REP_LEN + reclen;
                endlarge(fd);
                return(SUCCESS);
        }
}

1 則留言:

技術提供:Blogger.

Latest Photos

Join the Team

Blogger news

Popular Posts