10月19日闲的蛋疼,做了个
仿微信的聊天工具
git地址: https://github.com/killinux/mysocket/tree/master/websocket/project/Test
ui参考的网上例子http://ios.9tech.cn/news/2013/1111/38520.html
服务端用 tomcat7的websocket
客户端
1.可以用浏览器
2.sockroket的ios客户端,ios8,开发工具xcode6
ios客户端代码如下代码:
ViewController.m
// // ViewController.m // BubbleDemo // // Created by xiao7 on 14/10/19. // Copyright (c) 2014年 killinux. All rights reserved. // #import "ViewController.h" @interface ViewController () @end @implementation ViewController NSString *websocket_url = @"ws://192.168.0.102:8080/webs/websocket/test"; NSString *myName = @"haoning"; NSString *toName = @"all"; - (void)viewDidLoad { [super viewDidLoad]; //----init data---begin---- // NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"weixin",@"name",@"这是一个测试",@"content", nil]; // NSDictionary *dict1 = [NSDictionary dictionaryWithObjectsAndKeys:@"haoning",@"name",@"hello",@"content", nil]; // NSDictionary *dict7 = [NSDictionary dictionaryWithObjectsAndKeys:@"weixin",@"name",@",长数据测试。",@"content", nil]; // _resultArray = [NSMutableArray arrayWithObjects:dict,dict1, nil]; // [_resultArray addObject:dict7]; _resultArray = [[NSMutableArray alloc] init]; //----init data---end---- //websocket---begin--- _mywebSocket.delegate = nil; [_mywebSocket close]; _mywebSocket = [[SRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:websocket_url]]]; _mywebSocket.delegate = self; [_mywebSocket open]; NSLog(@"open success!"); //websocket---end---- } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } //pragma websocket - (void)webSocketDidOpen:(SRWebSocket *)webSocket; { NSLog(@"Websocket Connected"); self.title = @"Connected!"; } - (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error; { NSLog(@":( Websocket Failed With Error %@", error); _mywebSocket = nil; } - (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message; { NSLog(@"websocket Received \"%@\"", message); NSArray *messageArray = [message componentsSeparatedByString:@","]; if(messageArray.count<3){ NSLog(@"error parameter not right:%@",message); // NSDictionary *dict8 = [NSDictionary dictionaryWithObjectsAndKeys:@"haoning",@"name",message,@"content", nil]; // [_resultArray addObject:dict8]; }else{ NSDictionary *dict8 = [NSDictionary dictionaryWithObjectsAndKeys:messageArray[0],@"name",messageArray[2],@"content", nil]; [_resultArray addObject:dict8]; } [tableViewList reloadData]; } - (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean; { NSLog(@"WebSocket closed"); self.title = @"Connection Closed! (see logs)"; _mywebSocket = nil; } //发送消息 - (IBAction)sendBubbleMessage:(id)sender { NSString *thistext = messageTxt.text; NSLog(@"sendBubbleMessage:%@",thistext); // NSDictionary *dict8 = [NSDictionary dictionaryWithObjectsAndKeys:@"haoning",@"name",thistext,@"content", nil]; // [_resultArray addObject:dict8]; // [tableViewList reloadData]; NSString *sendMessage =[myName stringByAppendingFormat:@",%@,%@",toName,thistext]; [_mywebSocket send:sendMessage]; messageTxt.text=nil; } //泡泡文本 - (UIView *)bubbleView:(NSString *)text from:(BOOL)fromSelf withPosition:(int)position{ //计算大小 UIFont *font = [UIFont systemFontOfSize:14]; CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(180.0f, 20000.0f) lineBreakMode:NSLineBreakByWordWrapping]; // build single chat bubble cell with given text UIView *returnView = [[UIView alloc] initWithFrame:CGRectZero]; returnView.backgroundColor = [UIColor clearColor]; //背影图片 UIImage *bubble = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:fromSelf?@"SenderAppNodeBkg_HL":@"ReceiverTextNodeBkg" ofType:@"png"]]; UIImageView *bubbleImageView = [[UIImageView alloc] initWithImage:[bubble stretchableImageWithLeftCapWidth:floorf(bubble.size.width/2) topCapHeight:floorf(bubble.size.height/2)]]; //NSLog(@"%f,%f",size.width,size.height); UILabel *bubbleText = [[UILabel alloc] initWithFrame:CGRectMake(fromSelf?15.0f:22.0f, 20.0f, size.width+10, size.height+10)]; bubbleText.backgroundColor = [UIColor clearColor]; bubbleText.font = font; bubbleText.numberOfLines = 0; bubbleText.lineBreakMode = NSLineBreakByWordWrapping; bubbleText.text = text; bubbleImageView.frame = CGRectMake(0.0f, 14.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+20.0f); if(fromSelf) returnView.frame = CGRectMake(320-position-(bubbleText.frame.size.width+30.0f), 0.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+30.0f); else returnView.frame = CGRectMake(position, 0.0f, bubbleText.frame.size.width+30.0f, bubbleText.frame.size.height+30.0f); [returnView addSubview:bubbleImageView]; [returnView addSubview:bubbleText]; return returnView; } //泡泡语音 - (UIView *)yuyinView:(NSInteger)logntime from:(BOOL)fromSelf withIndexRow:(NSInteger)indexRow withPosition:(int)position{ //根据语音长度 int yuyinwidth = 66+fromSelf; UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; button.tag = indexRow; if(fromSelf) button.frame =CGRectMake(320-position-yuyinwidth, 10, yuyinwidth, 54); else button.frame =CGRectMake(position, 10, yuyinwidth, 54); //image偏移量 UIEdgeInsets imageInsert; imageInsert.top = -10; imageInsert.left = fromSelf?button.frame.size.width/3:-button.frame.size.width/3; button.imageEdgeInsets = imageInsert; [button setImage:[UIImage imageNamed:fromSelf?@"SenderVoiceNodePlaying":@"ReceiverVoiceNodePlaying"] forState:UIControlStateNormal]; UIImage *backgroundImage = [UIImage imageNamed:fromSelf?@"SenderVoiceNodeDownloading":@"ReceiverVoiceNodeDownloading"]; backgroundImage = [backgroundImage stretchableImageWithLeftCapWidth:20 topCapHeight:0]; [button setBackgroundImage:backgroundImage forState:UIControlStateNormal]; UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(fromSelf?-30:button.frame.size.width, 0, 30, button.frame.size.height)]; label.text = [NSString stringWithFormat:@"%d''",logntime]; label.textColor = [UIColor grayColor]; label.font = [UIFont systemFontOfSize:13]; label.textAlignment = NSTextAlignmentCenter; label.backgroundColor = [UIColor clearColor]; [button addSubview:label]; return button; } #pragma UITableView - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _resultArray.count; } -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSDictionary *dict = [_resultArray objectAtIndex:indexPath.row]; UIFont *font = [UIFont systemFontOfSize:14]; CGSize size = [[dict objectForKey:@"content"] sizeWithFont:font constrainedToSize:CGSizeMake(180.0f, 20000.0f) lineBreakMode:NSLineBreakByWordWrapping]; return size.height+44; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; cell.selectionStyle = UITableViewCellSelectionStyleNone; }else{ for (UIView *cellView in cell.subviews){ [cellView removeFromSuperview]; } } NSDictionary *dict = [_resultArray objectAtIndex:indexPath.row]; //创建头像 UIImageView *photo ; if ([[dict objectForKey:@"name"]isEqualToString:@"haoning"]) { photo = [[UIImageView alloc]initWithFrame:CGRectMake(320-60, 10, 50, 50)]; [cell addSubview:photo]; photo.image = [UIImage imageNamed:@"photo1"]; if ([[dict objectForKey:@"content"] isEqualToString:@"0"]) { [cell addSubview:[self yuyinView:1 from:YES withIndexRow:indexPath.row withPosition:65]]; }else{ [cell addSubview:[self bubbleView:[dict objectForKey:@"content"] from:YES withPosition:65]]; } }else{ photo = [[UIImageView alloc]initWithFrame:CGRectMake(10, 10, 50, 50)]; [cell addSubview:photo]; photo.image = [UIImage imageNamed:@"photo"]; if ([[dict objectForKey:@"content"] isEqualToString:@"0"]) { [cell addSubview:[self yuyinView:1 from:NO withIndexRow:indexPath.row withPosition:65]]; }else{ [cell addSubview:[self bubbleView:[dict objectForKey:@"content"] from:NO withPosition:65]]; } } return cell; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { } @end
ViewController.h
// // ViewController.h // BubbleDemo // // Created by xiao7 on 14/10/19. // Copyright (c) 2014年 killinux. All rights reserved. // #import#import "SocketRocket/SRWebSocket.h" @interface ViewController : UIViewController { IBOutlet UITableView *tableViewList; IBOutlet UITextField *messageTxt; } @property (nonatomic, strong) NSMutableArray *resultArray; @property (nonatomic, strong) SRWebSocket *mywebSocket; @end

演示
chrome上

ios8系统上

html的客户端
Insert title here 您的名字:
java的tomcat7的后台:
package com.hao; import java.io.DataInputStream; import java.io.IOException; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.Random; import javax.servlet.http.HttpServletRequest; import org.apache.catalina.websocket.MessageInbound; import org.apache.catalina.websocket.StreamInbound; import org.apache.catalina.websocket.WebSocketServlet; import org.apache.catalina.websocket.WsOutbound; public class HelloWorldWebSocketServlet extends WebSocketServlet { public static MapmmiList = new HashMap (); protected StreamInbound createWebSocketInbound(String subProtocol, HttpServletRequest arg1) { return new MyMessageInbound(); } public int getUserCount(){ return mmiList.size(); } private class MyMessageInbound extends MessageInbound { WsOutbound myoutbound; String mykey; @Override public void onOpen(WsOutbound outbound) { try { System.out.println("Open Client."); this.myoutbound = outbound; mykey ="open "+System.currentTimeMillis();; mmiList.put(mykey, this); System.out.println("mmiList size:"+mmiList.size()); outbound.writeTextMessage(CharBuffer.wrap(mykey)); } catch (IOException e) { e.printStackTrace(); } } @Override public void onClose(int status) { System.out.println("Close Client."); //mmiList.remove(this); mmiList.remove(mykey); } @Override protected void onBinaryMessage(ByteBuffer arg0) throws IOException { } @Override protected void onTextMessage(CharBuffer message) throws IOException { // TODO Auto-generated method stub System.out.println("onText--->" + message.toString()); // for (int i=0;i< mmiList.size();i++ ) { // MyMessageInbound mmib = (MyMessageInbound) mmiList.get(i); // CharBuffer buffer = CharBuffer.wrap(message); // mmib.myoutbound.writeTextMessage(buffer); // mmib.myoutbound.flush(); // } for (Map.Entry entry : mmiList.entrySet()) { //System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue()); MyMessageInbound mmib = (MyMessageInbound) entry.getValue(); // String str = entry.getKey()+message.toString() CharBuffer buffer = CharBuffer.wrap(message); mmib.myoutbound.writeTextMessage(buffer); mmib.myoutbound.flush(); } /*Socket socket; String msg = ""; try { // 向服务器利用Socket发送信息 socket = new Socket("192.168.0.102", 5000); // socket = new Socket("127.0.0.1",5000); PrintWriter output = new PrintWriter(socket.getOutputStream()); output.write(message.toString()); output.flush(); // 这里是接收到Server的信息 DataInputStream input = new DataInputStream( socket.getInputStream()); byte[] b = new byte[1024]; input.read(b); // Server返回的信息 msg = new String(b).trim(); output.close(); input.close(); socket.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } // 往浏览器发送信息 CharBuffer cb = CharBuffer.wrap(new StringBuilder(msg)); getWsOutbound().writeTextMessage(cb);*/ } } public static void main(String[] args) { Socket socket; String message = "haoning"; String msg = ""; try { // 向服务器利用Socket发送信息 socket = new Socket("192.168.0.102", 5000); // socket = new Socket("127.0.0.1",5000); PrintWriter output = new PrintWriter(socket.getOutputStream()); output.write(message.toString()); output.flush(); // 这里是接收到Server的信息 DataInputStream input = new DataInputStream(socket.getInputStream()); byte[] b = new byte[1024]; input.read(b); // Server返回的信息 msg = new String(b).trim(); output.close(); input.close(); socket.close(); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
web.xml
wsSnake com.hao.HelloWorldWebSocketServlet wsSnake /websocket/test