java中的socekt和WebSocekt

来源:互联网 发布:spss mac 编辑:程序博客网 时间:2024/06/05 14:10

1、什么是socekt

      Socket是应用层与TCP/IP协议族通信的中间软件抽象层,它是一组接口。在设计模式中,Socket其实就是一个门面模式,它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

2、服务端

package com.test.chat;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;import java.util.ArrayList;import java.util.List;public class Server {List<client> list = new ArrayList<>();ServerSocket ss = null;public static void main(String[] args) {new Server().start();}public void start() {try {ss = new ServerSocket(8888);while (true) {Socket socket = ss.accept();client c = new client(socket);//每增加一个客户端链接 就增加一个线程Thread t = new Thread(c);t.start();list.add(c);System.out.println("当前连接数是:"+list.size());}} catch (IOException e) {e.printStackTrace();}finally{try {if(null!=ss){ss.close();}} catch (IOException e) {e.printStackTrace();}}}class client implements Runnable {Socket socket = null;DataInputStream dis = null;DataOutputStream dos = null;public client(Socket socket) {this.socket = socket;}@Overridepublic void run() {try {dis = new DataInputStream(socket.getInputStream());while (true) {String str = dis.readUTF();System.out.println(str);for (client c : list) {Socket s = c.socket;dos = new DataOutputStream(s.getOutputStream());dos.writeUTF(str);}}} catch (IOException e) {System.out.println("断开连接");} finally {list.remove(this);try {if (null != dis)dis.close();if(null!=dos) dos.close();if (null != socket)socket.close();} catch (IOException e) {e.printStackTrace();}}}}}

3、客户端

package com.test.chat;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.IOException;import java.net.ConnectException;import java.net.Socket;import java.util.Scanner;public class Client {public static void main(String[] args) {new Client().start();}public void start(){try {Socket socket = new Socket("127.0.0.1",8888);DataOutputStream dos = new DataOutputStream(socket.getOutputStream());Scanner scan = new Scanner(System.in);new Thread(new result(new DataInputStream(socket.getInputStream()))).start();while(true){dos.writeUTF(scan.next());}}catch(ConnectException e){System.out.println("连接服务器失败!");} catch (IOException e) {System.err.println("");e.printStackTrace();}}class result implements Runnable{DataInputStream dis = null;public result(DataInputStream dis) {this.dis = dis;}@Overridepublic void run() {try {while(true){System.out.println(dis.readUTF());}} catch (IOException e) {System.out.println("服务器关闭了。。。。");e.printStackTrace();}finally{if(null!=dis){try {dis.close();} catch (IOException e) {e.printStackTrace();}}}}}}



WebSocekt是啥

WebSocket    是客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用ws或wss协议,可用于任意的客户端和服务器程序。


1、实现ServerApplicationConfig接口     该接口在tomcat目录下lib中的websocekt-api.jar中

public class Config implements ServerApplicationConfig{@Overridepublic Set<Class<?>> getAnnotatedEndpointClasses(Set<Class<?>> arg0) {return arg0;}@Overridepublic Set<ServerEndpointConfig> getEndpointConfigs(Set<Class<? extends Endpoint>> arg0) {return null;}}

2、写个类 ,我且当成是服务类。在类上添加@serverEndpoint("/")注解,括号中是页面访问该类的路径。

@ServerEndpoint("/wbt")public class Server {private static Map<String,Session> map = new HashMap<>();String userName;public Server() {System.out.println("Create Connection!");}/** * 创建连接 * @param session */@OnOpenpublic void onOpen(Session session){System.out.println("client connected! \t sessionId:"+session.getId());String queryString = session.getQueryString();try {userName = URLDecoder.decode(queryString.split("=")[1], "UTF-8");//解码} catch (UnsupportedEncodingException e) {e.printStackTrace();}this.map.put(userName, session);String msg = "Welcome "+ userName + " to chat!";Message message = new Message();message.setWelcome(msg);message.setUserNames(map.keySet());broadcast(new ArrayList<Session>(map.values()),message.toJson());}/** * 向页面传送消息 * @param ss * @param msg */public void broadcast(List<Session> ss, String msg) {for (Session session : ss) {try {session.getBasicRemote().sendText(msg);} catch (IOException e) {e.printStackTrace();}}}/** * 获取页面传过来的内容 * @param message * @param session */@OnMessagepublic void onMessage(String message,Session session){JSONObject json = JSONObject.fromObject(message);System.out.println(json.toString()+json.getString("msg"));Message msg = new Message();msg.setContent(this.userName, json.getString("msg"));msg.setUserNames(map.keySet());broadcast(new ArrayList<Session>(map.values()), msg.toJson());}/** * 关闭连接 * @param session */@OnClosepublic void onClose(Session session){System.out.println("session :"+ session.getId() + "已关闭");map.remove(this.userName);String msg = this.userName + " exit chat!";Message message = new Message();message.setWelcome(msg);message.setUserNames(map.keySet());broadcast(new ArrayList<Session>(map.values()), message.toJson());}}

3、js代码

var name="<%=userName%>";var ws;//一个ws对象就是一个通信管道var target = 'ws:<%=allPath%>;//allPath = request.getServerName()+":"+request.getServerPort()+request.getContextPath()/wbt?name=' + name;window.onload = function() {if ("WebSocket" in window) {ws = new WebSocket(target);} else if ("MozWebSocket" in window) {ws = new MozWebSocket(target);} else {alert("WebSocket is not supported by this browser");return;}ws.onmessage = function(event) {eval("var msg = " + event.data + ";");var content = $("#content").val();if (undefined != msg.welcome) {$("#content").val(content + "\n" + msg.welcome);}if (undefined != msg.userNames) {$("#users").html("");$(msg.userNames).each(function() {$("#users").append(this + "</br>");})}if (undefined != msg.content) {$("#content").val(content + "\n" + msg.content);}}ws.onerror = function() {alert("连接出错");//当链接不上的时候会调用此方法}ws.onclose = function() {alert("连接关闭");//当链接不上的时候再调用onerror后会调用    当服务器宕机也会调用}}function subSend() {var val = $("#msg").val();obj = {msg : val};ws.send(JSON.stringify(obj));console.info(val);$("#msg").val("");}function clearInput() {$("#msg").val("");}





4、效果图

展示聊天信息使用的文本域,然而其不能自动的把最新消息滚动到可视区域,尚有待优化




贴上练习代码。。。

做备份,同时给需要的人。



0 0