當某個請求遇到服務器(運行在移動應用上的服務器)時,我試圖將視頻文件作爲響應提供服務。例如:某人前往http://mylocalip:8080/video,我想用視頻爲他服務。如何向特定請求提供遠程文件(從遠程SMB服務器獲取)
這個視頻文件可以存儲在本地,也可以是外部的。我開始嘗試爲位於SMB服務器上的文件提供服務,因此我嘗試使用此代碼從服務器獲取文件並將其返回(我知道它正在等待整個文件讀取而不是讀取和發送塊,但應該可以工作對吧?):
webServer.addDefaultHandlerForMethod("GET", requestClass: GCDWebServerRequest.self, processBlock: {request in
print("########\n########Request: \(request)")
let webrequested:GCDWebServerRequest = request;
let urlcita:String = String(webrequested.URL)
print("URL of requests\(urlcita)")
if urlcita.rangeOfString("videosmb") != nil{
print("It's a video SMB request")
//Test fake SMB file predefined. Read File using KxSMB
let route:String = "smb://192.168.1.205/ServidorAH/video.avi";
let extensFile:NSString = (route as NSString).pathExtension
let contentype = GCDWebServerGetMimeTypeForExtension(extensFile as String);
print("Content type MIME \(contentype)")
//Open SMB file using KxSMB
let authcredentials = KxSMBAuth.smbAuthWorkgroup("", username: "Guest", password: "");
let provider = KxSMBProvider.sharedSmbProvider()!
let archivoes = provider.fetchAtPath(route, auth: authcredentials)
//Switch to manually end the reading when switched to true. In the future will send chunks of data until the end, instead of reading the whole file first.
var interruptor:Bool = false
//Response Stream block
let responseStream: GCDWebServerStreamedResponse = GCDWebServerStreamedResponse(contentType: contentype, asyncStreamBlock: { completionBlock in
if (interruptor == true)
{
print("Test: End of reading")
completionBlock(NSData(), nil);
}
if archivoes!.isKindOfClass(NSError){
//It can not find the file, SMB error, so empty NSDATA to completion block
let errorcito:NSError = archivoes as! NSError
print("Error obteniendo archivo SMB: \(errorcito.localizedDescription)");
completionBlock(NSData(), nil);
}else{
print("Archivo SMB adecuado \(archivoes)")
let datos:NSData = archivoes!.readDataToEndOfFile()
//Print lenght of data (to check the size of the file)
print("Data lenght \(datos.length)")
//Set switch to true, so the next call will send an empty daya completion block
interruptor = true
//Send data chunk (in this case everything)
completionBlock(datos, nil);
}
})
return responseStream
}else{
//Default response
return GCDWebServerDataResponse(HTML:"<html><body><p>Hello World<br></p></body></html>")
}
但是,我不能讓它工作。我總是得到一個壞的管道錯誤,並且訪問Web服務器的網絡播放器(從Mac和iOS瀏覽)也不會播放任何內容。我也嘗試使用嵌入式iOS播放器記錄響應(KxMovie)。我得到的是這樣的:
[DEBUG] Did open connection on socket 19
[DEBUG] Connection received 177 bytes on socket 19
[DEBUG] Connection on socket 19 preflighting request "GET /videosmb" with 177 bytes body
[DEBUG] Connection on socket 19 processing request "GET /videosmb" with 177 bytes body
[DEBUG] Did connect
[DEBUG] Did start background task
[DEBUG] Connection sent 175 bytes on socket 19
...
使用從App內的本地播放器(KxMovie),這裏似乎被讀取文件頭,它得到正確的文件大小和視頻的尺寸。然而,它不會播放,它結束說它已經到達視頻的結尾(不播放它)。只是在這之後,Web服務器上顯示錯誤:
...
[ERROR] Error while writing to socket 19: Broken pipe (32)
[DEBUG] Did close connection on socket 19
[VERBOSE] [fe80::cd0:28cd:3a37:b871%en1:8080] fe80::cd0:28cd:3a37:b871%en1:50109 200 "GET /videosmb" (177 | 175)
[DEBUG] Did disconnect
[DEBUG] Did end background task
鑑於這是我第一次處理SMB服務器,我雖然也許我在做什麼錯誤的SMB的一部分,所以我決定去一個簡單的方法來測試。 這次我試圖提供存儲在遠程網絡服務器(不是SMB)上的簡單mp4文件。它也沒有工作。 最後,我嘗試提供包含在應用程序主包中的本地文件,並且發生了同樣的情況:什麼都沒有。下面是代碼:
webServer.addDefaultHandlerForMethod("GET", requestClass: GCDWebServerRequest.self, processBlock: {request in
print("########\n########Request: \(request)")
let webrequested:GCDWebServerRequest = request;
let url:String = String(webrequested.URL)
print("URL of request: \(url)")
if url.rangeOfString("video") != nil{
print("It's a video request")
let rutalocalita = (NSBundle.mainBundle()).pathForResource("video", ofType: "avi")
let datos = NSData(contentsOfFile: rutalocalita!)!
print("video size: \(datos.length)")
return GCDWebServerDataResponse(data: datos, contentType: "video/avi")
}else{
//Default Response: Simple web
return GCDWebServerDataResponse(HTML:"<html><body><p>Hello World<br></p></body></html>")
}
})
這是日誌的樣子:
[DEBUG] Did open connection on socket 19
[DEBUG] Connection received 177 bytes on socket 19
[DEBUG] Connection on socket 19 preflighting request "GET /video" with 177 bytes body
[DEBUG] Connection on socket 19 processing request "GET /video" with 177 bytes body
[DEBUG] Did connect
[DEBUG] Did start background task
[myCUSTOMDebug] Read 13584902 b. I'm going to send the response back to the request.
[DEBUG] Connection sent 173 bytes on socket 19
...
在這裏,我使用的應用程序內部跟蹤響應的本地播放,能夠讀取之類的東西:
header='HTTP/1.1 200 OK'
2015-10-17 17:51:41.571 videotvtest[262:14252] http_code=200
2015-10-17 17:51:41.571 videotvtest[262:14252] header='Cache-Control: no-cache'
2015-10-17 17:51:41.571 videotvtest[262:14252] header='Content-Length: 13584902'
2015-10-17 17:51:41.572 videotvtest[262:14252] header='Content-Type: video/avi'
2015-10-17 17:51:41.572 videotvtest[262:14252] header='Connection: Close'
2015-10-17 17:51:41.573 videotvtest[262:14252] header='Server: GCDWebServer'
...
[ERROR] Error while writing to socket 19: Broken pipe (32)
[DEBUG] Did close connection on socket 19
[VERBOSE] [fe80::cd0:28cd:3a37:b871%en1:8080] fe80::cd0:28cd:3a37:b871%en1:50155 200 "GET /video" (177 | 173)
netbios_ns_send_name_query, name query sent for '*'.
[DEBUG] Did disconnect
[DEBUG] Did end background task
我與tvOS和Xcode的7這個玩弄,但我想它應該是確定的,如果我能夠顯示普通的HTML迴應...所以我敢肯定,我錯過有些東西,或者我安裝時錯過了一些框架ling WebServer(我不使用豆莢)? 在此先感謝
您在SMB,視頻文件,手錶操作系統,網絡服務器之間的移動部件太多了......您應該先從Mac應用程序或iPhone應用程序提供常規本地文件,然後通過視頻文件提供,然後通過SMB最後移動到觀看操作系統。 – Pol
您好波爾,感謝您的回覆。然而,在我的代碼中沒有任何與操作系統相關的問題!經過更多測試後,這裏的主要問題似乎與內容範圍有關,因爲我可以從受測試的所有文件(本地,smb,遠程等)谷歌Chrome桌面完美無瑕! 但是,當我嘗試iOS播放器或OS X Safari時,它會失敗......在開發者控制檯中告訴我有關'未能加載資源:插件模塊管理'的信息。 我知道如果他們存儲在本地,可以提供某種範圍文件......但第三方呢?我應該首先在本地下載它們嗎? – eiprol
你應該更新這個問題的標題,因爲它太泛化,也不是真正的問題。 – Pol