我刚刚实现了这样的东西。如果上传失败或者只有一半字节到达主机,你会怎么做?
我们的方法是创建两个额外的方法,一个是客户端设备调用以检查先前上传的状态(称为“ GetStatusOfLastUpload(SessionID, DeviceID, FileID) ”),另一个称为ResumeUpload(SessionID, DeviceID, FileID, MD5Hash, Bytes ) .
函数GetStatusOfLastUpload顾名思义,向主机发送附加请求以检查先前上传的状态(存储在 SQL 数据库中)。
此过程的关键是使用计算的 MD5 哈希和字节计数来确定主机端是否已交付完整的文件。例如,如果客户端发送了1MB,但Host只得到了500KB,并且客户端发送的MD5哈希与主机根据接收到的字节计算的MD5不匹配,我们将上传数据记录的状态设置为“未完成" 并存储字节数。因此,当调用GetStatusOfLastUpload时,主机返回(如有必要)最后一次上传是“未完成”并且接收到的字节数仅为 500KB。
然后,客户端应用程序从GetStatusOfLastUpload获取此信息并调用“ ResumeUpload ”,发送完整文件的 MD5 散列和主机需要的剩余字节。主机再次收到此信息后,将字节组合并计算 MD5 哈希,并将其与客户端发送的值进行比较。如果哈希值匹配,您就知道您有一个完整的文件,如果不匹配,请重复该过程。
这里没有办法包含所有示例代码,但我会说我们的 ResumeUpload 函数看起来与我们的 Upload 函数相同,但包含一些额外的检查以确保一切正确。
_ __ _ __ _ __ _ __ _ __ _ __ _ ___编辑_ __ _ __ _ __ _ __ _ _ _ __ _ __ _ __ _ _
我们在客户端使用 .NET 的东西,但这是一些示例 Java 代码(更适合 Android),我为那些在非 Windows 设备上开发的人准备了一些代码。它构造与 WCF 主机(也是 .NET)交换的消息。
public MsgStruct CallHost(String URL, String Content, byte[] outBytes){
String textValue="";
byte[] inBytes =new byte[] {0};
try {
// Creating a new empty SOAP message object
SOAPMessage reqMsg = MessageFactory.newInstance().createMessage();
// Populating SOAP body
SOAPEnvelope envelope = reqMsg.getSOAPPart().getEnvelope();
SOAPBody body = envelope.getBody();
SOAPBodyElement service = body.addBodyElement(envelope.createName("HostConnect", "", WCFNameSpace)); //good here
SOAPElement paramInMsg = service.addChildElement(envelope.createName("inMsg", "", "")); //good here
//SOAPElement paramBodySection = paramInMsg.addChildElement(envelope.createName("BodySection", "", DataContractNameSpace));
SOAPElement paramTextSection = paramInMsg.addChildElement(envelope.createName("TextSection", "", DataContractNameSpace));
SOAPElement paramBodySection = paramInMsg.addChildElement(envelope.createName("BodySection", "", DataContractNameSpace));
//get the byte array to send and populate the fields
String sOut=org.apache.commons.codec.binary.Base64.encodeBase64String(outBytes);
paramBodySection.addTextNode(sOut); //adding the binary stuff here "AA=="
paramTextSection.addTextNode(Content); //adding the text content here
envelope.removeAttribute("Header");
envelope.setPrefix("s");
envelope.getBody().setPrefix("s");
// Setting SOAPAction header line
MimeHeaders headers = reqMsg.getMimeHeaders();
headers.addHeader("SOAPAction", SoapAction); //good here
headers.setHeader("Content-Type", "text/xml; charset=utf-8"); //good here
headers.setHeader("Host", "Localhost:8085"); //good here
headers.setHeader("Expect", "100-continue");
// Connecting and Calling
SOAPConnection con = SOAPConnectionFactory.newInstance().createConnection();
SOAPMessage resMsg = con.call(reqMsg, URL);
resMsg.saveChanges();
con.close();
//check the host response
if (resMsg != null){
try{
SOAPBody responseBody = resMsg.getSOAPBody();
SOAPBodyElement responseElement0= (SOAPBodyElement)responseBody.getChildElements().next();
SOAPElement responseElement1 = (SOAPElement)responseElement0.getChildElements().next();
SOAPElement TextElement = (SOAPElement)responseElement1.getFirstChild();
SOAPElement bodyElement = (SOAPElement)responseElement1.getLastChild();
Node nodeBody = (Node)bodyElement;
inBytes = getBytesFromDoc(nodeBody);
textValue = TextElement.getTextContent();
}catch (SOAPException se){
String smessage = se.getMessage();
}
return new MsgStruct(textValue,inBytes);
//no response from host
}else{
Debug.println("error","Error- nothign found");
return null;
}
} catch (Exception e) {
Debug.println("error",e.getMessage());
return null;
}
}
在主机方面,要共享的代码太多了,但概念在上面的帖子中。要记住的是,WCF(几乎)始终是客户端请求/主机响应方案,因此客户端设备需要启动所有内容,包括检查最后一次上传是否成功。遵循我的建议?
这对您来说可能是一个很好的信息来源:http: //fszlin.dymetis.com/post/2010/05/10/Comsuming-WCF-Services-With-Android.aspx