Java 服务器端的web套接字连接管理
我在服务器端使用web套接字。我设法从应用程序连接到服务器,并向每个打开的连接发送消息/通知 -如何识别连接(即打开的websocket),以便用户可以(通过websocket)向特定用户发送消息/通知。这是我的代码首先是桌面客户端代码Java 服务器端的web套接字连接管理,java,jsp,tomcat,servlets,websocket,Java,Jsp,Tomcat,Servlets,Websocket,我在服务器端使用web套接字。我设法从应用程序连接到服务器,并向每个打开的连接发送消息/通知 -如何识别连接(即打开的websocket),以便用户可以(通过websocket)向特定用户发送消息/通知。这是我的代码首先是桌面客户端代码 if( e.getSource() == connect ) { try { cc = new WebSocketClient( new URI( "http://localhost:8080/webSocket/chat
if( e.getSource() == connect ) {
try {
cc = new WebSocketClient( new URI( "http://localhost:8080/webSocket/chatServlet"), (Draft) draft.getSelectedItem() ) {
@Override
public void onMessage( String message ) {
ta.append( "got: " + message + "\n" );
ta.setCaretPosition( ta.getDocument().getLength() );
}
@Override
public void onOpen( ServerHandshake handshake ) {
ta.append( "You are connected to ChatServer: " + getURI() + "\n" );
ta.setCaretPosition( ta.getDocument().getLength() );
}
@Override
public void onClose( int code, String reason, boolean wasClean ) {
ta.append( "You have been disconnected from: " + getURI() + "; Code: " + code + " " + reason + "\n" );
System.out.println("the reason for disconnection is ........ "+wasClean);
ta.setCaretPosition( ta.getDocument().getLength() );
connect.setEnabled( true );
uriField.setEditable( true );
draft.setEditable( true );
close.setEnabled( false );
}
@Override
public void onError( Exception ex ) {
ta.append( "Exception occured ...\n" + ex + "\n" );
ta.setCaretPosition( ta.getDocument().getLength() );
ex.printStackTrace();
connect.setEnabled( true );
uriField.setEditable( true );
draft.setEditable( true );
close.setEnabled( false );
}
};
close.setEnabled( true );
connect.setEnabled( false );
uriField.setEditable( false );
draft.setEditable( false );
cc.connect();
} catch ( URISyntaxException ex ) {
ta.append( uriField.getText() + " is not a valid WebSocket URI\n" );
}
} else if( e.getSource() == close ) {
cc.close();
}
}
现在这里是服务器端代码
public class SocketListener extends WebSocketServlet {
/**
*
*/
private static final long serialVersionUID = 1L;
private static ArrayList<MyStreamBound> mmiList = new ArrayList<MyStreamBound>();
private HttpServletRequest request;
private String clientName;
private String zone;
private String subId;
@Override
protected StreamInbound createWebSocketInbound(String protocol) {
System.out.println("protocol values are..."+protocol);
return new MyStreamBound();
}
private class MyStreamBound extends StreamInbound{
WsOutbound myoutbound;
public MyStreamBound(){
super();
}
@Override
public void onOpen(WsOutbound outbound){
try {
System.out.println("Open Client."+outbound.toString()+" and value of this "+this.toString());
this.myoutbound = outbound;
mmiList.add(this);
outbound.writeTextMessage(CharBuffer.wrap("Hello!"));
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
protected void onBinaryData(InputStream arg0) throws IOException {
// TODO Auto-generated method stub
}
@Override
protected void onTextData(Reader recievedData) throws IOException {
BufferedReader in = new BufferedReader(recievedData);
String line = null;
StringBuilder rslt = new StringBuilder();
while ((line = in.readLine()) != null) {
rslt.append(line);
}
System.out.println(rslt.toString());
for(MyStreamBound mmib: mmiList){
CharBuffer buffer = CharBuffer.wrap(rslt.toString());
mmib.myoutbound.writeTextMessage(buffer);
mmib.myoutbound.flush();
}
}
@Override
protected void onClose(int status){
System.out.println("Close Client."+status);
mmiList.remove(this);
}
}
公共类SocketListener扩展了WebSocketServlet{
/**
*
*/
私有静态最终长serialVersionUID=1L;
私有静态ArrayList mmiList=新ArrayList();
私有HttpServletRequest;
私有字符串clientName;
私有字符串区;
私有字符串子ID;
@凌驾
受保护的StreamInbound createWebSocketInbound(字符串协议){
System.out.println(“协议值为…”+协议);
返回新的MyStreamBound();
}
私有类MyStreamBound扩展StreamInbound{
WSM是向外的;
公共MyStreamBound(){
超级();
}
@凌驾
公共无效onOpen(WsOutbound-outbound){
试一试{
System.out.println(“Open Client.+outbound.toString()+”和this的值“+this.toString());
this.myoutbound=出站;
mmiList.添加(此);
outbound.writeTextMessage(CharBuffer.wrap(“Hello!”);
}捕获(IOE异常){
e、 printStackTrace();
}
}
@凌驾
受保护的void onBinaryData(InputStream arg0)引发IOException{
//TODO自动生成的方法存根
}
@凌驾
受保护的void onTextData(读卡器接收数据)引发IOException{
BufferedReader in=新的BufferedReader(接收数据);
字符串行=null;
StringBuilder rslt=新的StringBuilder();
而((line=in.readLine())!=null){
rslt.append(行);
}
System.out.println(rslt.toString());
用于(MyStreamBound mmib:mmiList){
CharBuffer=CharBuffer.wrap(rslt.toString());
mmib.myoutbound.writeTextMessage(缓冲区);
mmib.myoutbound.flush();
}
}
@凌驾
受保护的void onClose(int状态){
System.out.println(“关闭客户端”+状态);
删除(此);
}
}
}我最近也遇到了同样的问题 你有一些选择
protected StreamInbound createWebSocketInbound(String protocol, HttpServletRequest req) {
System.out.println("protocol values are..."+protocol);
return new MyStreamBound(req.getSession().getId());
}
for(MyStreamBound mmib: mmiList){
CharBuffer buffer = CharBuffer.wrap(rslt.toString());
mmib.myoutbound.writeTextMessage(buffer);
mmib.myoutbound.flush();
}
它从mmiList生成一个迭代器,如果您有多个并发访问(这就是WebSocket的用途),它将导致异常。我是这样写的(即使它看起来不那么好):
for(int i=0;i
这样,您就不会在创建集合和使代码线程安全方面遇到麻烦。事实上,我对此有点失望,但这就是增强的for循环在Java中的工作方式
正常的for循环没有那么有效。我不明白为什么mmiList不是线程安全的集合,它没有任何意义。您也可以检查这些备选方案:如果您不想使用普通for循环。我最近也遇到了同样的问题 你有一些选择
protected StreamInbound createWebSocketInbound(String protocol, HttpServletRequest req) {
System.out.println("protocol values are..."+protocol);
return new MyStreamBound(req.getSession().getId());
}
for(MyStreamBound mmib: mmiList){
CharBuffer buffer = CharBuffer.wrap(rslt.toString());
mmib.myoutbound.writeTextMessage(buffer);
mmib.myoutbound.flush();
}
它从mmiList生成一个迭代器,如果您有多个并发访问(这就是WebSocket的用途),它将导致异常。我是这样写的(即使它看起来不那么好):
for(int i=0;i
这样,您就不会在创建集合和使代码线程安全方面遇到麻烦。事实上,我对此有点失望,但这就是增强的for循环在Java中的工作方式
正常的for循环没有那么有效。我不明白为什么mmiList不是线程安全的集合,它没有任何意义。您也可以检查这些备选方案:如果您不想使用普通for循环。谢谢您的建议。我特别关注ArrayList这一点,现在我正在使用CopyOnArrayList,正如您所建议的,不客气。希望其他部分也能帮上忙。。。如果您的服务要处理许多用户,您必须非常小心这一部分,因为任何错误都可能导致严重的性能问题…谢谢您的建议。我特别关注ArrayList这一点,现在我正在使用CopyOnArrayList,正如您所建议的,不客气。希望其他部分也能帮上忙。。。如果你的服务要处理许多用户,你必须非常小心