【发布时间】:2017-05-17 14:59:37
【问题描述】:
我正在使用的代码只有在我让它作为阻塞例程运行时才有效……但如果我使用go executeTheFunction,我总是会得到panic: runtime error: invalid memory address or nil pointer dereference。稍微总结一下代码就是这样。
func (c App) Index() revel.Result {
app = c; //this is a "global" variable to be used in callBackFunction
options = "foo";
client = NewClient()
client.RequestAsynch(options, callBackFunction);
}
func callBackFunction(message string){
reader := bytes.NewBufferString(message)
_, err := xmlpath.Parse( reader )
if err != nil {
panic(err)
}
flusher, ok := airshopping.Response.Out.(http.Flusher)
if !ok {
panic("expected http.ResponseWriter to be an http.Flusher")
}
fmt.Fprintf(airshopping.Response.Out, "whatever")
flusher.Flush()
}
func (client * Client)RequestAsynch(message Message, callback func(string)) {
Response := client.Request(message)
message_aux := ""
reader := bufio.NewReader(Response.Body)
for {
line, err := reader.ReadBytes('\n')
if err==nil {
message_aux = message_aux + string(line)
if strings.Contains(message_aux, "<!-- AG-EOM -->"){
go callback(message_aux)
message_aux = ""
}
}else{fmt.Println("ERROR", err);break;}
}
}
好的...我将解释一下。 RequestAsynch 位于不同的包中,它向其他服务器发起请求。这个其他服务器响应多个 xml...这些 xml 的主体看起来像:
<!-- Header status:ok -->
<all_the_xml_response>
<!-- AG-EOM -->
所以...当逐行循环检测到这个"<!-- AG-EOM -->" 是完全接收到其中一个xml 时,应该执行回调函数(使用gorutine)。这个callBack函数的任务是解析xml,经过一个解析过程,将一些数据发送回客户端的javascript。
我总是遇到的错误是:
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x0 addr=0x20 pc=0x4f8c09]
goroutine 80 [running]:
bufio.(*Writer).Write(0xc042454540, 0xc0422d4000, 0x11076, 0x12000, 0xc04202fb30, 0x4683b7, 0x11076)
C:/Go/src/bufio/bufio.go:598 +0x149
net/http.(*response).write(0xc04234d0a0, 0x11076, 0xc0422d4000, 0x11076, 0x12000, 0x0, 0x0, 0xc0422d4000, 0x0, 0x0)
C:/Go/src/net/http/server.go:1525 +0x157
net/http.(*response).Write(0xc04234d0a0, 0xc0422d4000, 0x11076, 0x12000, 0x0, 0x0, 0xc042824000)
C:/Go/src/net/http/server.go:1495 +0x6b
fmt.Fprintf(0xb65e80, 0xc04234d0a0, 0xc042824000, 0x11076, 0x0, 0x0, 0x0, 0xc0421445f0, 0xb, 0xc0422f5e00)
C:/Go/src/fmt/print.go:182 +0xb0
ndc-console-test/app/controllers/ndcmethods.GetOffers_AS(0xc042594000, 0xef7f)
F:/Proyectos_Trabajo/work/src/ndc-console- test/app/controllers/ndcmethods/airshopping.go:98 +0x7a1
created by github.com/open-ndc/ndc-go-sdk.(*Client).RequestAsynch
F:/Proyectos_Trabajo/work/src/github.com/open-ndc/ndc-go-sdk/ndc_client.go:143 +0x25c
2017/05/17 16:42:56 reverseproxy.go:316: http: proxy error: dial tcp [::1]:55058: connectex:A connection can not be established because the target computer expressly denied the connection.
出现此错误后...我需要重新启动服务器,因为它不允许建立新连接。
我看到的一件事是,如果我在 callBackFunction 中删除这一行 _, err := xmlpath.Parse( reader ) ,它就可以正常工作。当然,如果我更改此行:go callback(message_aux) 为callback(message_aux)(没有 goroutine)它也可以正常工作,并且解析 xml 没有问题。
有谁知道如何使用 goroutines 避免这个错误的解决方案?
非常感谢。
编辑
我认为我没有很好地表达自己对其他服务器的响应方式,这是(多个)响应的外观:
<!-- Header status:ok -->
<the_xml_response_of_one_response_or_one_chunk>
<!-- AG-EOM -->
<!-- Header status:ok -->
<other_xml_response>
<!-- AG-EOM -->
<!-- Header status:ok -->
<other_more_xml_response>
<!-- AG-EOM -->
【问题讨论】:
-
http.ResponseWriter 仅在请求的生命周期内有效。在 Go 中没有理由使用这样的异步回调模式。
标签: go xml-parsing request buffer goroutine