我正在使用的代码仅在我将其作为阻止例程运行时才有效...但如果我使用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被完全接收,并且应该执行callBack函数(使用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 -->
答案 0 :(得分:0)
根据您的堆栈跟踪,似乎问题是一旦父函数返回就会写出HTTP响应,到新goroutine有机会尝试时,编写器不再可用。< / p>
这是net/http
设计的一部分,因此我怀疑您的RequestAsynch
无法按照预期编写。为什么需要异步?每个请求都已在自己的goroutine中处理。
BTW,strings.NewReader
可能比bytes.NewBufferString
更合适,因为您不需要完整的缓冲区接口。