Windows Phone 7使用HTTP Basic认证连接gsoap编写的WebService

6 篇文章 0 订阅
6 篇文章 0 订阅

服务端使用gsoap库(版本为2.8.9),参考官方示例的httpdatest.c编写,服务的内容很简单,传入两个整数,返回它们的和。

1.先编译安装gsoap 2.8.9,你也可以安装最新的版本,可以得到soapcpp2

2.创建wsaddgsoapserverdefine.h,定义一个web service method

int ns__wsadd(int a, int b, int *result);

3.使用soapcpp2生成需要的其他文件

soapcpp2 -c wsaddgsoapserverdefine.h

4.修改生成的ns.wsdl,将

<SOAP:address location="http://localhost:80"/>

改为实际服务器的IP(域名)和服务端口,比如

<SOAP:address location="http://192.168.1.132:8000"/>

5.创建wsaddgsoapserver.c,编写服务核心代码

#include "httpda.h"
#include "soapH.h"
#include "ns.nsmap"

int run_serve(int port);

int main(int argc, char *argv[])
{
	return run_serve(8000);
}

int run_serve(int port)
{
	struct soap *soap = soap_new1(SOAP_XML_INDENT);
	int ret;
	soap_register_plugin(soap, http_da);
	if (!soap_valid_socket(soap_bind(soap, NULL, port, 100)))
		soap_print_fault(soap, stderr);
	else
	{
		fprintf(stderr, "Bind to port %d successful\n", port);
		soap->accept_timeout = 3600; /* let server time out after one hour */
		for (;;)
		{
			int sock = soap_accept(soap);
			if (!soap_valid_socket(sock))
			{
				if (soap->errnum)
					soap_print_fault(soap, stderr);
				else
				{
					fprintf(stderr, "Server timed out\n");
					break;
				}
			}
			fprintf(stderr, "Accepting socket %d connection from IP %d.%d.%d.%d\n", sock, (int)(soap->ip>>24)&0xFF, (int)(soap->ip>>16)&0xFF, (int)(soap->ip>>8)&0xFF, (int)soap->ip&0xFF);
			if (soap_serve(soap))
				soap_print_fault(soap, stderr);
			fprintf(stderr, "Served\n\n");
			soap_destroy(soap);
			soap_end(soap);
		} 
	}
	ret = soap->error;
	soap_destroy(soap);
	soap_end(soap);
	soap_free(soap);
	return ret;
}

int ns__wsadd(struct soap *soap, int a, int b, int *result)
{ 
	if (soap->userid && soap->passwd)	/* Basic authentication: the password was sent in the clear */
	{ 
		if (!strcmp(soap->userid, "username") && !strcmp(soap->passwd, "password"))
		{
			*result=a+b;
			return SOAP_OK;
		}
	}
	return 401; /* Not authorized */
} 

6.编辑stdsoap2.c,修改http_get函数的实现,目的是接下来Visual Studio中添加服务引用时能够发现该服务。修改如下:

//static int
//http_get(struct soap *soap)
//{ (void)soap;
//  DBGLOG(TEST, SOAP_MESSAGE(fdebug, "HTTP GET request\n"));
//  return SOAP_GET_METHOD;
//}

static int
http_get(struct soap *soap)
{
	FILE *fd = NULL;
	char *s = strchr(soap->path, '?'); 
	if (!s || strcmp(s, "?wsdl")) 
	{
		return SOAP_GET_METHOD; 
	}
	fd = fopen("ns.wsdl", "rb"); // open WSDL file to copy 
	if (!fd) 
	{
		return 404; // return HTTP not found error 
	}
	soap->http_content = "text/xml"; // HTTP header with text/xml content 
	soap_response(soap, SOAP_FILE); 
	for (;;) 
	{ 
		size_t r = fread(soap->tmpbuf, 1, sizeof(soap->tmpbuf), fd); 
		if (!r) 
		{
			break; 
		}
		if (soap_send_raw(soap, soap->tmpbuf, r)) 
		{
			break; // can't send, but little we can do about that 
		}
	} 
	fclose(fd); 
	soap_end_send(soap); 
	return SOAP_OK;  
}

7.编译生成服务端

gcc -DWITH_OPENSSL -o wsaddgsoapserver wsaddgsoapserver.c soapC.c soapServer.c httpda.c md5evp.c threads.c stdsoap2.c -lssl -lcrypto -lz

8../wsaddgsoapserver运行服务端,可以在浏览器中输入http://192.168.1.132:8000/?wsdl,查看服务端的http get服务部分是否正常工作

9.编写Windows Phone客户端,新建一个Windows Phone工程(如果没有的话),右键解决方案中的引用,添加服务引用,在地址栏输入http://192.168.1.132:8000/?wsdl,点击前往,VS将自动连接服务端解析出服务端提供的服务以及方法,如下:



10.自定义命名空间,比如WSAddServiceReference,点击确定就可以使用了。

11.客户端核心代码如下:

private string EncodeBasicAuthenticationCredentials(string username, string password)
{
    //first concatenate the user name and password, separated with :
    string credentials = username + ":" + password;

    //Http uses ascii character encoding, WP7 doesn’t include
    // support for ascii encoding but it is easy enough to convert
    // since the first 128 characters of unicode are equivalent to ascii.
    // Any characters over 128 can’t be expressed in ascii so are replaced
    // by ?
    var asciiCredentials = (from c in credentials
                            select c <= 0x7f ? (byte)c : (byte)'?').ToArray();

    //finally Base64 encode the result
    return Convert.ToBase64String(asciiCredentials);
}

private void button_CallWSAdd_Click(object sender, RoutedEventArgs e)
{
    WSAddServiceReference.ServicePortTypeClient SPTC = new WSAddServiceReference.ServicePortTypeClient();
    SPTC.wsaddCompleted += (s, arg) =>
    {
        if (arg.Error != null)
        {

            textBox_WSAddResult.Text = string.Format("Error:{0}", arg.Error.Message);
            return;
        }
        textBox_WSAddResult.Text = arg.Result.ToString();
    };

    var credentials = EncodeBasicAuthenticationCredentials("username", "password");

    using (OperationContextScope scope = new OperationContextScope(SPTC.InnerChannel))
    {
        HttpRequestMessageProperty request = new HttpRequestMessageProperty();
        request.Headers[System.Net.HttpRequestHeader.Authorization] = "Basic " + credentials;

        OperationContext.Current.OutgoingMessageProperties.Add(HttpRequestMessageProperty.Name, request);
        SPTC.wsaddAsync(int.Parse(textBox_WSAddArgA.Text), int.Parse(textBox_WSAddArgB.Text));
    }
}

12.编译运行客户端,和服务端交互的界面如下:


13.抓包结果如下:

POST / HTTP/1.1
Accept: */*
Referer: file:///Applications/Install/89591F69-A04D-4BEF-B181-4FA364ECD820/Install/
Content-Length: 179
Accept-Encoding: identity
Content-Type: text/xml; charset=utf-8
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
SOAPAction: ""
User-Agent: NativeHost
Host: 192.168.1.132:8000
Connection: Keep-Alive
Cache-Control: no-cache

<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><wsadd xmlns="http://tempuri.org/ns.xsd"><a xmlns="">12</a><b xmlns="">34</b></wsadd></s:Body></s:Envelope>

HTTP/1.1 200 OK
Server: gSOAP/2.8
Content-Type: text/xml; charset=utf-8
Content-Length: 436
Connection: close

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://tempuri.org/ns.xsd">
	<SOAP-ENV:Body>
		<ns:wsaddResponse>
			<result>46</result>
		</ns:wsaddResponse>
	</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

14.服务端完整代码可以在这里下载: http://download.csdn.net/detail/chenxupro/6400275

15.客户端完整代码也可以在我的资源里面下载,链接暂时还看不到。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值