WebSocket是什么呢?

  WebSocket一种在单个 TCP 连接上进行全双工通讯的协议。WebSocket通信协议于2011年被IETF定为标准RFC 6455,并被RFC7936所补充规范,WebSocketAPI被W3C定为标准。

WebSocket 是独立的、创建在 TCP 上的协议,和 HTTP 的唯一关联是使用 HTTP 协议的101状态码进行协议切换,使用的 TCP 端口是80,可以用于绕过大多数防火墙的限制。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端直接向客户端推送数据而不需要客户端进行请求,在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并允许数据进行双向传送。

目前常见的浏览器如 Chrome、IE、Firefox、Safari、Opera 等都支持 WebSocket,同时需要服务端程序支持 WebSocket。

    --------------------------------------------------------------------------------------

以上摘自wiki,总的来说websocket实现了服务器和浏览器之间的双向通信,摆脱了以往的一问一答的通信方式,可以自由地传输数据.

Websocket有什么优点?

  • 由于没有http头信息,所以传输的数据包很小
  • 服务器可以主动推送信息

Websocket的握手协议

还是照搬wiki上的例子,websocket在建立连接时,浏览器会向服务器发出如下请求

GET / HTTP/1.1
Upgrade: websocket
Connection: Upgrade
Host: example.com
Origin: null
Sec-WebSocket-Key: sN9cRrP/n9NdMgdcy2VJFQ==
Sec-WebSocket-Version: 13

这段请求会告诉服务器即将切换到websocket协议,如果服务器支持的话,会返回如下信息

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: fFBooB7FAkLlXgRSz0BT3v4hq5s=
Sec-WebSocket-Origin: null
Sec-WebSocket-Location: ws://example.com/

至此,握手阶段完成,服务器和浏览器之间可以开始发送和接收信息

使用Websocket实现一个简单的网页聊天室

  • 使用tomcat8的websocket-api
  • 参考tomcat自带的example

服务器端ChatServlet

package com.yc.chatroom;
import java.io.IOException;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.atomic.AtomicInteger;
import javax.servlet.annotation.WebServlet;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;
@ServerEndpoint(value="/websocket/chat")//指定客户端连接地址
public class ChatServlet {
  private static final long serialVersionUID = 1L;
  private static final String GUEST_PREFIX = "Guest";
  private static final AtomicInteger connectionIds = new AtomicInteger(0);
  private static final Set<ChatServlet> connections = new CopyOnWriteArraySet<ChatServlet>();
  private final String nickname;
  private Session session;
  public ChatServlet() {
    nickname = GUEST_PREFIX + connectionIds.getAndIncrement();
  }
  @OnOpen
  public void start(Session session) {
    this.session = session;
    connections.add(this);
    String message = String.format("* %s %s", nickname, "has joined.");
    broadcast(message); //广播用户加入消息
  }
  @OnClose
  public void end() {
    connections.remove(this);
    String message = String.format("* %s %s", nickname, "has disconnected.");
    broadcast(message); //广播用户推出消息
  }
  @OnMessage
  public void incoming(String message) {
    // Never trust the client
    String filteredMessage = String.format("%s: %s", nickname, message.toString());
    broadcast(filteredMessage); //广播发送内容
  }
  @OnError
  public void onError(Throwable t) throws Throwable {
    t.printStackTrace();
  }
  private static void broadcast(String msg) {
    for (ChatServlet client : connections) {
      try {
        synchronized (client) {
          client.session.getBasicRemote().sendText(msg);//给每个人发送消息
        }
      } catch (IOException e) {
        connections.remove(client);
        try {
          client.session.close();
        } catch (IOException e1) {
          // Ignore
        }
        String message = String.format("* %s %s", client.nickname, "has been disconnected.");
        broadcast(message);
      }
    }
  }
}

浏览器端index.jsp

<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<html>
<head>
<title>Apache Tomcat WebSocket Examples: Chat</title>
<style type="text/css">
input#chat {
  width: 410px
}
#console-container {
  width: 400px;
}
#console {
  border: 1px solid #CCCCCC;
  border-right-color: #999999;
  border-bottom-color: #999999;
  height: 170px;
  overflow-y: scroll;
  padding: 5px;
  width: 100%;
}
#console p {
  padding: 0;
  margin: 0;
}
</style>
</head>
<body>
  <div>
    <p>
      <input type="text" placeholder="type and press enter to chat"
        id="chat" />
    </p>
    <div id="console-container">
      <div id="console"></div>
    </div>
  </div>
</body>
<script type="text/javascript">
  /**
  *  指定要连接的websocket地址
  *  如果使用https,则使用wss://
  **/
  var socket = new WebSocket('ws://' + window.location.host+ '/chatroom/websocket/chat');

  //连接与服务器的连接
  socket.onopen = function() {
    showMsg('Info: WebSocket connection opened.');
    document.getElementById('chat').onkeydown = function(event) {
      if (event.keyCode == 13) {
        sendMsg();
      }
    };
  };
  //断开与服务器的连接
  socket.onclose = function() {
    document.getElementById('chat').onkeydown = null;
    showMsg('Info: WebSocket closed.');
  };
  //与服务器之间的通信
  socket.onmessage = function(message) {
    showMsg(message.data);
  };
  //显示消息
  function showMsg(message) {
    var console = document.getElementById('console');
    var p = document.createElement('p');
    p.style.wordWrap = 'break-word';
    p.innerHTML = message;
    console.appendChild(p);
    while (console.childNodes.length > 25) {
      console.removeChild(console.firstChild);
    }
    console.scrollTop = console.scrollHeight;
  }
  //发送消息
  function sendMsg() {
    var message = document.getElementById('chat').value;
    if (message != '') {
      socket.send(message);
      document.getElementById('chat').value = '';
    }
  }
</script>

运行结果

一次打开两个窗口,用户依次为guest0, guest1

guest0:

guest1:

guest0退出:

原文链接地址:https://mssora.com/websocket-intro-and-chatroom/

WebSocket介绍和一个简单的聊天室的更多相关文章

  1. 基于websocket实现的一个简单的聊天室

    本文是基于websocket写的一个简单的聊天室的例子,可以实现简单的群聊和私聊.是基于websocket的注解方式编写的.(有一个小的缺陷,如果用户名是中文,会乱码,不知如何处理,如有人知道,请告知 ...

  2. [SignalR]一个简单的聊天室

    原文:[SignalR]一个简单的聊天室 1.说明 开发环境:Microsoft Visual Studio 2010 以及需要安装NuGet. 2.添加SignalR所需要的类库以及脚本文件: 3. ...

  3. 用ServletContext做一个简单的聊天室

    这里主要是ServletContext的一个特性:ServletContext是一个公共的空间,可以被所有的客户访问.由此可见ServletContext比cookie和session的作用范围要大[ ...

  4. ASP.NET Signalr 2.0 实现一个简单的聊天室

    学习了一下SignalR 2.0,http://www.asp.net/signalr 文章写的很详细,如果头疼英文,还可以机翻成中文,虽然不是很准确,大概还是容易看明白. 理论要结合实践,自己动手做 ...

  5. 如何用WebSocket实现一个简单的聊天室以及单聊功能

    百度百科中这样定义WebSocket:WebSocket协议是基于TCP的一种新的网络协议.它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端.简单的说,We ...

  6. 通过WebSocket实现一个简单的聊天室功能

    WebSocket WebSocket是一个协议,它是是基于TCP的一种新的网络协议,TCP协议是一种持续性的协议,和HTTP不同的是,它可以在服务器端主动向客户端推送消息.通过这个协议,可以在建立一 ...

  7. 使用ASP.NET SignalR实现一个简单的聊天室

    前言 距离我写上一篇博客已经又过了一年半载了,时间过得很快,一眨眼,就把人变得沧桑了许多.青春是短暂的,知识是无限的.要用短暂的青春,去学无穷无尽的知识,及时当勉励,岁月不待人.今天写个随笔小结记录一 ...

  8. node实现一个简单的聊天室(认识一下socket)

    边学边理解node的高深,今天写了一个聊天室的demo,很简单,认识一下socket node服务端代码 var express = require('express'); var app = exp ...

  9. 利用JavaUDPSocket+多线程模拟实现一个简单的聊天室程序

    对Socket的一点个人理解:Socket原意是指插座.家家户户都有五花八门的家用电器,但它们共用统一制式的插座.这样做的好处就是将所有家用电器的通电方式统一化,不需要大费周章地在墙壁上凿洞并专门接电 ...

随机推荐

  1. ASE周会记录

    本周Sprint Master Atma Hou 一. 本周会议概要 本次会议的主要任务是明确和老师讨论后的数据库设计定稿,同时为我们接下来的连接工作确定包含实现细节的story和接口. 二. 会议内 ...

  2. DUT Star Weekly Contest #3 Problem F Solution

    题目链接 问题转化 \[a_i+a_j+(i-j)^2=a_i+i^2+a_j+j^2-2ij\] 令 \(b_i=a_i+i^2\) , 问题化为: 求 \[\max \{b_i+b_j-2ij\} ...

  3. shell脚本自动拉起启动程序

    一.我们先看看编写的shell脚本的内容,该shell的作用主要是实现监控某个程序崩溃之后就自动重启该进程. while true do procnum=` ps -ef|grep "tes ...

  4. win7搭建双系统ubuntu

    参考链接:http://www.linuxidc.com/Linux/2014-10/108430.htm 0.下载EasyBCD软件和ubuntu镜像1.在win7,右键我的电脑,磁盘管理,压缩卷, ...

  5. widows和Linux java加密注意事项

    /** * @Title: EncrypAES.java * @Package com.weidinghuo.payment.util * @Description: TODO(用一句话描述该文件做什 ...

  6. Jquery实现特效滑动菜单栏

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 第一章 Part 2/2 Git 一览

    被跟踪文件(Tracked files) 被跟踪文件是 Git 管理的工作目录 (存储库) 中的文件.当你添加新文件或使更新现有文件时,Git都会跟踪这些文件变化.在某个时间点,你将通过命令将这些文件 ...

  8. [Exchange 2013]创建约会和会议

    简介 会议和约会之间的重要区别是,会议有与会者,并且没有约会.约会和会议可以是单实例或属于重复序列,但与会者. 房间或资源中不包括约会,因为它们不需要发送一条消息.在内部,Exchange 使用相同的 ...

  9. vim保存文件时,生成.un~文件

    在用vim保存文件时,文件夹下生成.un~文件 怎么删除这些文件呢 在网上搜索的答案: http://stackoverflow.com/questions/15660669/what-is-a-un ...

  10. C语言: 运算符,printf,scanf的用法

    运算符/的运算结果和运算对象的数据类型有关,两个数都是in,则商就是int,取整数部分:被除数和除数中只要有一个或两个都是浮点型数据,则商也是浮点型,不去掉小数部分如:16/5 == 3:16/5.0 ...