Android客户端SignalR握手时negotiate接口返回404 Not Found错误
SignalR协商接口404错误排查(Postman正常,Android客户端失败)
我正在做一个POC(概念验证),需要和SignalR建立连接并订阅通知,但调用第一个negotiate接口时就碰到404错误。奇怪的是,用相同的URL和自定义请求头在Postman里请求却能成功。
客户端代码(SignalRClient.java)
import android.util.Log; import com.microsoft.signalr.HubConnection; import com.microsoft.signalr.HubConnectionBuilder; import com.microsoft.signalr.HubConnectionState; import com.microsoft.signalr.TransportEnum; import java.util.HashMap; import java.util.Map; public class SignalRClient { private static final String TAG = "xxxxxxx"; private static final String HUB_URL = "xxxxxxx"; private final HubConnection hubConnection; public SignalRClient(String token, String username) { Map<String, String> headers = new HashMap<>(); headers.put("token", token); headers.put("userName", username); // 构建连接 hubConnection = HubConnectionBuilder .create(HUB_URL) .withHeaders(headers) .withTransport(TransportEnum.LONG_POLLING) .build(); } public void startConnection() { if (hubConnection != null && hubConnection.getConnectionState() == HubConnectionState.DISCONNECTED) { hubConnection.start() .blockingAwait(); // 建议异步处理结果,避免阻塞 Log.d(TAG, "Connection started"); } } public void stopConnection() { if (hubConnection != null && hubConnection.getConnectionState() == HubConnectionState.CONNECTED) { hubConnection.stop(); Log.d(TAG, "Connection stopped"); } } public void sendMessage(String message) { if (hubConnection != null && hubConnection.getConnectionState() == HubConnectionState.CONNECTED) { hubConnection.send("SendMessage", message); Log.d(TAG, "Message sent: " + message); } else { Log.e(TAG, "连接未建立或已关闭,无法发送消息"); } } }
排查要点
- URL正确性检查:确认
HUB_URL是否完全匹配Postman中使用的地址,包括末尾是否带斜杠、路由后缀(如/hub)是否正确。注意Android端是否存在URL编码异常,导致实际请求路径与预期不符。 - 请求头一致性验证:用抓包工具(如Charles)查看Android客户端发出的negotiate请求头,和Postman的请求头逐一对比,确认
token、userName等自定义头是否正确传递,是否存在大小写差异或遗漏的默认头(如Content-Type)。 - 替换阻塞调用捕获异常:
blockingAwait()会阻塞线程且无法直接捕获连接异常,建议换成异步订阅方式获取详细错误信息:
异常栈能帮你定位404的具体原因,比如路由不匹配、权限问题等。hubConnection.start().subscribe( () -> Log.d(TAG, "连接成功"), throwable -> Log.e(TAG, "连接失败", throwable) ); - 传输模式与后端配置匹配:确认后端SignalR是否启用了长轮询(Long Polling)传输模式,虽然Postman能正常请求negotiate,但需排查后端是否对客户端有特殊限制。
- 网络环境与权限检查:确保Android应用已申请
INTERNET权限;如果测试环境需要代理,检查客户端是否配置了正确的代理,避免请求无法到达后端。
内容的提问来源于stack exchange,提问作者Sudhansu
相关产品推荐
相关产品推荐

