{"record":{"id":"552950e64cc5ca0e","repo":"unknwon/the-way-to-go_ZH_CN","slug":"dial-err-error","errorCode":null,"errorMessage":"\"Dial: \" + err.Error()","messagePattern":"\"Dial: \" \\+ err\\.Error\\(\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"eBook/15.11.md","lineNumber":58,"sourceCode":"\t}\n}\n```\n\n示例 15.25 [websocket_client.go](examples/chapter_15/websocket_client.go)\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\t\"websocket\"\n)\n\nfunc main() {\n\tws, err := websocket.Dial(\"ws://localhost:12345/websocket\", \"\",\n\t\t\"http://localhost/\")\n\tif err != nil {\n\t\tpanic(\"Dial: \" + err.Error())\n\t}\n\tgo readFromServer(ws)\n\ttime.Sleep(5e9)\n    ws.Close()\n}\n\nfunc readFromServer(ws *websocket.Conn) {\n\tbuf := make([]byte, 1000)\n\tfor {\n\t\tif _, err := ws.Read(buf); err != nil {\n\t\t\tfmt.Printf(\"%s\\n\", err.Error())\n\t\t\tbreak\n\t\t}\n\t}\n}\n```\n\n## 链接","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/unknwon/the-way-to-go_ZH_CN/blob/7a54d34d3657084b6a59e5618bd069b912d571aa/eBook/15.11.md#L40-L76","documentation":"Panic in the WebSocket client (section 15.11): websocket.Dial(\"ws://localhost:12345/websocket\", \"\", \"http://localhost/\") failure aborts with panic(\"Dial: \" + err.Error()) before the readFromServer goroutine ever starts. The message embeds the dial error, typically 'connection refused' or an origin-handshake rejection.","triggerScenarios":"Dial returns an error: the server example is not running or listens elsewhere (port/path mismatch), the URL scheme is not ws://, or the third argument (origin 'http://localhost/') is rejected by the endpoint's origin check.","commonSituations":"Starting the client before the server (connection refused); server bound to 127.0.0.1 while the client reaches for another interface; port typos between the two listings; modern websocket libraries enforcing origin policies more strictly than the old 'websocket' package","solutions":["Start the WebSocket server example first and confirm it is accepting on :12345 before running the client","Match host, port, and path exactly with the server's handler route (/websocket)","Use the same modern library (golang.org/x/net/websocket or gorilla/websocket) on both ends so the handshake matches","Retry Dial a few times with a short backoff — dev servers routinely come up a beat after their clients","Replace the panic with log.Fatal(\"Dial: \", err) for a clean, logged exit"],"exampleFix":"// before\nws, err := websocket.Dial(\"ws://localhost:12345/websocket\", \"\", \"http://localhost/\")\nif err != nil {\n    panic(\"Dial: \" + err.Error())\n}\n\n// after\nws, err := websocket.Dial(\"ws://localhost:12345/websocket\", \"\", \"http://localhost/\")\nfor i := 0; err != nil && i < 3; i++ {\n    time.Sleep(500 * time.Millisecond)\n    ws, err = websocket.Dial(\"ws://localhost:12345/websocket\", \"\", \"http://localhost/\")\n}\nif err != nil {\n    log.Fatal(\"Dial: \", err)\n}","handlingStrategy":"validation","validationCode":"// verify the server endpoint before the websocket handshake\nif c, err := net.DialTimeout(\"tcp\", \"localhost:12345\", time.Second); err != nil {\n    log.Fatal(\"websocket server not up on localhost:12345:\", err)\n} else {\n    c.Close()\n}\nws, err := websocket.Dial(\"ws://localhost:12345/websocket\", \"\", \"http://localhost/\")","typeGuard":null,"tryCatchPattern":"// bounded retry instead of panic on first failure\nws, err := websocket.Dial(addr, \"\", origin)\nfor i := 0; err != nil && i < 3; i++ {\n    time.Sleep(300 * time.Millisecond)\n    ws, err = websocket.Dial(addr, \"\", origin)\n}\nif err != nil {\n    log.Fatal(\"Dial: \", err)\n}","preventionTips":["Start the server before the client; keep one shared constant for host, port, and path","Keep the origin argument consistent with the dial host to pass origin checks","Use the same websocket library/version on both ends so handshakes match"],"tags":["go","websocket","client","dial","connection-refused","panic"],"backgroundTag":null,"analyzedSha":"7a54d34d3657084b6a59e5618bd069b912d571aa","analyzedAt":"2026-08-15T15:13:06.026Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}