项目篇------------网页五子棋(知识预备)
1.websocketpp协议
1.初步介绍
原理解析:
WebSocket协议本质上是⼀个基于TCP的协议。为了建⽴⼀个WebSocket连接,客⼾端浏览器⾸先要向服务器发起⼀个HTTP请求,这个请求和通常的HTTP请求不同,包含了⼀些附加头信息,通过这个附加头信息完成握⼿过程并升级协议的过程
那么升级的具体过程是什么呢?:
2.具体使用
namespace websocketpp {
typedef lib::weak_ptr<void> connection_hdl;template <typename config> class endpoint : public config::socket_type {typedef lib::shared_ptr<lib::asio::steady_timer> timer_ptr;typedef typename connection_type::ptr connection_ptr;typedef typename connection_type::message_ptr message_ptr;typedef lib::function<void(connection_hdl)> open_handler;typedef lib::function<void(connection_hdl)> close_handler;typedef lib::function<void(connection_hdl)> http_handler;typedef lib::function<void(connection_hdl, message_ptr)> message_handler;//-----------------以上都是重新定义的内容,使用时要用加上websocket::endpoint:: !!!!!!!!!/* websocketpp::log::alevel::none 禁⽌打印所有⽇志*/void set_access_channels(log::level channels); /*设置⽇志打印等级*/void clear_access_channels(log::level channels); /*清除指定等级的⽇志*/ //-----------------------------------日志接口,基本不用/*设置指定事件的回调函数*///--------四种回调函数都要由我们自己声明!!!!!void set_open_handler(open_handler h); /*websocket握⼿成功回调处理函数*/void set_close_handler(close_handler h); /*websocket连接关闭回调处理函数*/void set_message_handler(message_handler h); /*websocket消息回调处理函数*/--------//比如消息被发过来了,如何处理,比如聊天/下棋void set_http_handler(http_handler h); /*http请求回调处理函数*/-----------//因为wesocket是从http切换过来的,所以切换前需要使用http协议,例如请求登录网页!!!!
//-----------------------------针对不同的请求和数据内容,调用对应的回调函数!!!/*发送数据接⼝*/void send(connection_hdl hdl, std::string& payload,frame::opcode::value op);void send(connection_hdl hdl, void* payload, size_t len,frame::opcode::value op);
//-----------------------------------------------------/*关闭连接接⼝*/void close(connection_hdl hdl, close::status::value code,std::string& reason);//---------------------------------------------------/*获取connection_hdl 对应连接的connection_ptr*/connection_ptr get_con_from_hdl(connection_hdl hdl);/*websocketpp基于asio框架实现,init_asio⽤于初始化asio框架中的io_service调度器*///-------------------------------------------------void init_asio();/*设置是否启⽤地址重⽤*/void set_reuse_addr(bool value);/*设置endpoint的绑定监听端⼝*/void listen(uint16_t port);//------不必多说,TCP服务端必须要有,才能进行监听!!!!/*对io_service对象的run接⼝封装,⽤于启动服务器*/std::size_t run();//---启动服务器//--------------------------------------------------/*websocketpp提供的定时器,以毫秒为单位*/timer_ptr set_timer(long duration, timer_handler callback);
};//设置定时任务,规划某个任务需要在多少秒后进行//--------------这些都是endpoint类的内容----------------------//--------------------------------------------------------template <typename config>//继承endpoint类
class server : public endpoint<connection<config>, config> {/*初始化并启动服务端监听连接的accept事件处理*/void start_accept();
};//----------------------------------------server类---------//connection类template <typename config>class connection : public config::transport_type::transport_con_type,public config::connection_base {/*发送数据接⼝*/error_code send(std::string& payload,frame::opcode::value op = frame::opcode::text);/*获取http请求头部*/std::string const& get_request_header(std::string const& key)/*获取请求正⽂*/std::string const& get_request_body();/*设置响应状态码*/void set_status(http::status_code::value code);/*设置http响应正⽂*/void set_body(std::string const& value);/*添加http响应头部字段*/void append_header(std::string const& key, std::string const& val);/*获取http请求对象*/request_type const& get_request();/*获取connection_ptr 对应的 connection_hdl */connection_hdl get_handle();
};//---------------------------------------------------很多是对http请求的函数//-----------------------------
namespace http {
namespace parser {
class parser {std::string const& get_header(std::string const& key)
} class request : public parser {/*获取请求⽅法*/std::string const& get_method()/*获取请求uri接⼝*/std::string const& get_uri()
};
} // namespace parser
}; // namespace httpnamespace message_buffer {
/*获取websocket请求中的payload数据类型*/
frame::opcode::value get_opcode();
/*获取websocket中payload数据*/
std::string const& get_payload();
}; // namespace message_buffernamespace log {
struct alevel {static level const none = 0x0;static level const connect = 0x1;static level const disconnect = 0x2;static level const control = 0x4;static level const frame_header = 0x8;static level const frame_payload = 0x10;static level const message_header = 0x20;static level const message_payload = 0x40;static level const endpoint = 0x80;static level const debug_handshake = 0x100;static level const debug_close = 0x200;static level const devel = 0x400;static level const app = 0x800;static level const http = 0x1000;static level const fail = 0x2000;static level const access_core = 0x00003003;static level const all = 0xffffffff;
};
} // namespace lognamespace http {
namespace status_code {
enum value {uninitialized = 0,continue_code = 100,switching_protocols = 101,ok = 200,created = 201,accepted = 202,non_authoritative_information = 203,no_content = 204,reset_content = 205,partial_content = 206,multiple_choices = 300,moved_permanently = 301,found = 302,see_other = 303,not_modified = 304,use_proxy = 305,temporary_redirect = 307,bad_request = 400,unauthorized = 401,payment_required = 402,forbidden = 403,not_found = 404,method_not_allowed = 405,not_acceptable = 406,proxy_authentication_required = 407,request_timeout = 408,conflict = 409,gone = 410,length_required = 411,precondition_failed = 412,request_entity_too_large = 413,request_uri_too_long = 414,unsupported_media_type = 415,request_range_not_satisfiable = 416,expectation_failed = 417,im_a_teapot = 418,upgrade_required = 426,precondition_required = 428,too_many_requests = 429,request_header_fields_too_large = 431,internal_server_error = 500,not_implemented = 501,bad_gateway = 502,service_unavailable = 503,gateway_timeout = 504,http_version_not_supported = 505,not_extended = 510,network_authentication_required = 511
};
}
} // namespace http
namespace frame {
namespace opcode {
enum value {continuation = 0x0,text = 0x1,binary = 0x2,rsv3 = 0x3,rsv4 = 0x4,rsv5 = 0x5,rsv6 = 0x6,rsv7 = 0x7,close = 0x8,ping = 0x9,pong = 0xA,control_rsvb = 0xB,control_rsvc = 0xC,control_rsvd = 0xD,control_rsve = 0xE,control_rsvf = 0xF,
};
}
} // namespace frame
} // namespace websocketpp
3.服务器搭建过程
#include <iostream>
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
using namespace std;
typedef websocketpp::server<websocketpp::config::asio> websocketsvr;
typedef websocketsvr::message_ptr message_ptr;
using websocketpp::lib::bind;
using websocketpp::lib::placeholders::_1;
using websocketpp::lib::placeholders::_2;
// websocket连接成功的回调函数
void OnOpen(websocketsvr* server, websocketpp::connection_hdl hdl) {cout << "连接成功" << endl;
}
// websocket连接成功的回调函数
void OnClose(websocketsvr* server, websocketpp::connection_hdl hdl) {cout << "连接关闭" << endl;
}
// websocket连接收到消息的回调函数
void OnMessage(websocketsvr* server, websocketpp::connection_hdl hdl,message_ptr msg) {cout << "收到消息" << msg->get_payload() << endl;// 收到消息将相同的消息发回给websocket客⼾端server->send(hdl, msg->get_payload(), websocketpp::frame::opcode::text);
}
// websocket连接异常的回调函数
void OnFail(websocketsvr* server, websocketpp::connection_hdl hdl) {cout << "连接异常" << endl;
}
// 处理http请求的回调函数 返回⼀个html欢迎⻚⾯
void OnHttp(websocketsvr* server, websocketpp::connection_hdl hdl) {cout << "处理http请求" << endl;websocketsvr::connection_ptr con = server->get_con_from_hdl(hdl);std::stringstream ss;ss << "<!doctype html><html><head>"<< "<title>hello websocket</title><body>"<< "<h1>hello websocketpp</h1>"<< "</body></head></html>";con->set_body(ss.str());con->set_status(websocketpp::http::status_code::ok);
}
int main() {// 使⽤websocketpp库创建服务器websocketsvr server;// 设置websocketpp库的⽇志级别// all表⽰打印全部级别⽇志// none表⽰什么⽇志都不打印server.set_access_channels(websocketpp::log::alevel::none);/*初始化asio*/server.init_asio();// 注册http请求的处理函数server.set_http_handler(bind(&OnHttp, &server, ::_1));// 注册websocket请求的处理函数server.set_open_handler(bind(&OnOpen, &server, ::_1));server.set_close_handler(bind(&OnClose, &server, _1));server.set_message_handler(bind(&OnMessage, &server, _1, _2));// 监听8888端⼝server.listen(8888);// 开始接收tcp连接server.start_accept();// 开始运⾏服务器server.run();return 0;
}
4.c++11中bind函数的使用
5.服务器尝试搭建
wserver.cpp:
#include<iostream> // 输入输出流头文件
#include<string> // 字符串处理头文件
#include<websocketpp/server.hpp> // WebSocket++服务器头文件
#include<websocketpp/config/asio_no_tls.hpp> // WebSocket++ ASIO非TLS配置头文件// 定义WebSocket服务器类型,使用ASIO非TLS配置
typedef websocketpp::server<websocketpp::config::asio> wsserver_t;// HTTP请求回调函数
void http_callback(wsserver_t* srv,websocketpp::connection_hdl hdl)
{// 第一步:通过连接句柄获取连接对象wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);// 打印请求体内容std::cout<<"body:"<<conn->get_request_body()<<std::endl;// 第二步:获取HTTP请求对象websocketpp::http::parser::request req = conn->get_request();// 打印HTTP请求方法(GET/POST等)std::cout<<"method:"<<req.get_method()<<std::endl;// 打印请求URIstd::cout<<"uri:"<<req.get_uri()<<std::endl;// 设置响应内容:一个简单的HTML页面std::string body="<html><body><h1>hello world</h1></body></html>";// 设置响应体conn->set_body(body);// 添加响应头,指定内容类型为HTMLconn->append_header("Content-type","text/html");// 设置HTTP状态码为200 OKconn->set_status(websocketpp::http::status_code::ok);
}// WebSocket连接打开回调函数
void wsopen_callback(wsserver_t* srv,websocketpp::connection_hdl hdl)
{std::cout<<"打开成功"<<std::endl;
}// WebSocket连接关闭回调函数
void wsclose_callback(wsserver_t* srv,websocketpp::connection_hdl hdl)
{std::cout<<"关闭成功"<<std::endl;
}// WebSocket消息接收回调函数
void wsmessage_callback(wsserver_t* srv,websocketpp::connection_hdl hdl,wsserver_t::message_ptr msg)
{// 打印接收到的消息内容std::cout<<"message:"<<msg->get_payload()<<std::endl;// 获取连接对象wsserver_t::connection_ptr conn = srv->get_con_from_hdl(hdl);// 构造响应消息(在客户端消息前加上"client say:")std::string rsp = "client say:"+msg->get_payload();// 发送响应消息conn->send(rsp);
}int main()
{// 1.创建WebSocket服务器实例wsserver_t server;// 2.设置日志级别:none表示不打印任何日志server.set_access_channels(websocketpp::log::alevel::none);// 3.初始化ASIO网络库server.init_asio();// 4.注册HTTP请求处理回调函数server.set_http_handler(std::bind(http_callback,&server,std::placeholders::_1));// 4.注册WebSocket连接打开回调函数server.set_open_handler(std::bind(wsopen_callback,&server,std::placeholders::_1));// 4.注册WebSocket连接关闭回调函数server.set_close_handler(std::bind(wsclose_callback,&server,std::placeholders::_1));// 4.注册WebSocket消息接收回调函数server.set_message_handler(std::bind(wsmessage_callback,&server,std::placeholders::_1,std::placeholders::_2));// 5.监听8081端口server.listen(8081);// 6.开始接受TCP连接server.start_accept();// 7.运行服务器(进入事件循环)server.run();return 0;
}
2.json库的使用
1.简要介绍
Json 是⼀种数据交换格式,它采⽤完全独⽴于编程语⾔的⽂本格式来存储和表⽰数据。
2.主要使用类的介绍
1.数据对象类
class Json::Value {Value&operator=(const Value& other); // Value重载了[]和=,因此所有的赋值和获取数据都可以通过Value& operator[](const std::string& key); // 简单的⽅式完成 val["name"] ="xx";Value& operator[](const char* key);Value removeMember(const char* key); // 移除元素const Value& operator[](ArrayIndex index) const; // val["score"][0]Value& append(const Value& value); // 添加数组元素val["score"].append(88);ArrayIndex size() const; // 获取数组元素个数 val["score"].size();bool isNull(); // ⽤于判断是否存在某个字段std::string asString() const; // 转string string name =val["name"].asString();const char* asCString() const; // 转char* char *name =val["name"].asCString();Int asInt() const; // 转int int age = val["age"].asInt();float asFloat() const; // 转float float weight = val["weight"].asFloat();bool asBool() const; // 转 bool bool ok = val["ok"].asBool();
};
2.序列化端口
class JSON_API StreamWriter {virtual int write(Value const& root, std::ostream* sout) = 0;
}
class JSON_API StreamWriterBuilder : public StreamWriter::Factory {virtual StreamWriter* newStreamWriter() const;
}
3.反序列化端口
class JSON_API CharReader {virtual bool parse(char const* beginDoc, char const* endDoc, Value* root, std::string* errs) = 0;
}
class JSON_API CharReaderBuilder : public CharReader::Factory {virtual CharReader* newCharReader() const;
}
4.代码示例
#include<iostream>
#include<sstream>
#include<string>
#include<vector>
#include <jsoncpp/json/json.h>std::string serialize()
{//1.将需要序列话的数据,存储到Json::Value种Json::Value root;root["姓名"]="小明";root["年龄"]=18;root["成绩"].append(98);root["成绩"].append(88.5);root["成绩"].append(78.5);//2.示例话一个StreamWriterBuilder工厂类Json::StreamWriterBuilder swb;//3.使用这个工厂类来生产一个StreamWriter对象Json::StreamWriter* sw =swb.newStreamWriter();//4.使用StreamWriter,对val里面的数据进行序列化std::stringstream ss;int ret=sw->write(root,&ss);//序列化if (ret != 0) {std::cout << "Serialize failed!\n";return ""; } std::cout << "序列化结果:\n" << ss.str() << std::endl;return ss.str();
}void unserialize(std::string str)
{//1.示例化一个Json::CharReaderBuilder工厂类Json::CharReaderBuilder crb;//2.通过这个工厂类来示例化一个Json::CharReader对象Json::CharReader* cr=crb.newCharReader();//3.初始化一个Json::Value对象来存储数据Json::Value root;std::string err;//4.使用CharReader对象对JSON格式的字符串str进行反序列化bool ret=cr->parse(str.c_str(),str.c_str()+str.size(),&root,&err);if(ret==false){std::cout<<"反序列化失败"<<err<<std::endl;return ;}//5.逐个访问value中的数据对象std::cout<<"姓名:"<<root["姓名"].asString()<<std::endl;std::cout<<"年龄:"<<root["年龄"].asInt()<<std::endl;int sz=root["成绩"].size();for(int i=0;i<sz;i++){std::cout<<"成绩:"<<root["成绩"][i].asFloat()<<std::endl;}
}int main()
{std::string str=serialize();//开始进行反序列化unserialize(str);return 0;
}
makefile:
json:json.cppg++ -std=c++11 $^ -o $@ -lpthread -lboost_system -ljsoncpp
wserver:wserver.cppg++ -std=c++11 $^ -o $@ -lpthread -lboost_system.PHONY:clean
clean:rm -rf json
3.mysql数据库的使用
1.操作流程
2.接口详解
// Mysql操作句柄初始化
// 参数说明:
// mysql为空则动态申请句柄空间进⾏初始化
// 返回值: 成功返回句柄指针, 失败返回NULL
MYSQL* mysql_init(MYSQL* mysql);
//---------------------------------------------------------// 连接mysql服务器// 参数说明:// mysql--初始化完成的句柄// host---连接的mysql服务器的地址// user---连接的服务器的⽤⼾名// passwd-连接的服务器的密码// db ----默认选择的数据库名称// port---连接的服务器的端⼝: 默认0是3306端⼝// unix_socket---通信管道⽂件或者socket⽂件,通常置NULL// client_flag---客⼾端标志位,通常置0// 返回值:成功返回句柄指针,失败返回NULLMYSQL* mysql_real_connect(MYSQL* mysql, const char* host, const char* user,const char* passwd, const char* db,unsigned int port, const char* unix_socket,unsigned long client_flag);//-----------------------------------------------------------// 设置当前客⼾端的字符集
// 参数说明:
// mysql--初始化完成的句柄
// csname--字符集名称,通常:"utf8"
// 返回值:成功返回0, 失败返回⾮0
int mysql_set_character_set(MYSQL* mysql, const char* csname)//--------------------------------------------------------------// 选择操作的数据库// 参数说明:// mysql--初始化完成的句柄// db-----要切换选择的数据库名称// 返回值:成功返回0, 失败返回⾮0int mysql_select_db(MYSQL* mysql, const char* db)
//-----------------------------------------------------------// 执⾏sql语句// 参数说明:// mysql--初始化完成的句柄// stmt_str--要执⾏的sql语句// 返回值:成功返回0, 失败返回⾮0int mysql_query(MYSQL* mysql, const char* stmt_str)
//------------------------------------------------------------// 保存查询结果到本地// 参数说明:// mysql--初始化完成的句柄// 返回值:成功返回结果集的指针, 失败返回NULLMYSQL_RES* mysql_store_result(MYSQL* mysql)
//------------------------------------------------------------// 获取结果集中的⾏数// 参数说明:// result--保存到本地的结果集地址// 返回值:结果集中数据的条数uint64_t mysql_num_rows(MYSQL_RES* result);
//----------------------------------------------------------// 获取结果集中的列数// 参数说明:// result--保存到本地的结果集地址// 返回值:结果集中每⼀条数据的列数unsigned int mysql_num_fields(MYSQL_RES* result)
//---------------------------------------------------------// 遍历结果集, 并且这个接⼝会保存当前读取结果位置,每次获取的都是下⼀条数据// 参数说明:// result--保存到本地的结果集地址// 返回值:实际上是⼀个char **的指针,将每⼀条数据做成了字符串指针数组// row[0]-第0列 row[1]-第1列 ...MYSQL_ROW mysql_fetch_row(MYSQL_RES* result)
//---------------------------------------------------------// 释放结果集// 参数说明:// result--保存到本地的结果集地址void mysql_free_result(MYSQL_RES* result)
//------------------------------------------------------// 关闭数据库客⼾端连接,销毁句柄// 参数说明:// mysql--初始化完成的句柄void mysql_close(MYSQL* mysql)
//-------------------------------------------------------// 获取mysql接⼝执⾏错误原因// 参数说明:// mysql--初始化完成的句柄const char* mysql_error(MYSQL* mysql)
//---------------------------------------------------------
3.终端建立数据库
1.建立新的数据库
登录mysql数据库后,运行以下指令:
- 建立了一个名为gobang的数据库!!!!!
2.进入新的数据库并建表
- desc加表名查看表中的内容!!!
4.撰写客户端调用数据库接口访问数据库
#include<stdio.h>
#include<string.h>
#include<mysql/mysql.h>#define HOST "127.0.0.1"//拒绝远程登录,所以使用127.0.0.1进行内网登录
#define PORT 3306
#define USER "root"
#define PASS "###############"------自己的密码
#define DBNAME "gobang"int main()
{//1.创建数据库句柄//MYSQL* mysql_init(MYSQL* mysql);MYSQL* mysql=mysql_init(NULL);if(mysql == NULL){printf("建立失败\n");return -1;}//2.连接数据库服务器//MYSQL *mysql_real_connect(mysql,host,user,pass,dbname,port,unix_socket,flag)if(mysql_real_connect(mysql,HOST,USER,PASS,DBNAME,PORT,NULL,0)==NULL){printf("连接数据库失败: %s\n",mysql_error(mysql));mysql_close(mysql);return -1;}//3.设置字符集,utf8//int mysql_set_character_set(mysql,"utf8")if(mysql_set_character_set(mysql,"utf8")!=0){printf("设置字符集失败: %s\n",mysql_error(mysql));mysql_close(mysql);return -1;}//4.选择要操作的数据库//int mysql_select_db(mysql,dbname)//mysql_select_db(mysql,DBNAME)---------这里不写的原因是上文mysql_real_connect已经设置过dbname了//5.执行sql语句---------增删改查//int mysql_query(MYSQL *mysql,char* sql);//char* sql="insert stu values(null,'张三',18,10,10,10);";//增//char* sql="update stu set ch=ch+30 where sn=1;";//改//char* sql="delete from stu where sn=1;";//删char* sql = "select * from stu;";//查询if(mysql_query(mysql,sql)!=0){printf("添加内容失败: %s\n",mysql_error(mysql));mysql_close(mysql);return -1;}//6.如果是查询语句。那么就把结果保留到本地//MYSQL_RES * mysql_store_result(MYSQL* mysql);--------------------------------------------res就是结果集!!!!!!!!!!!!MYSQL_RES * res= mysql_store_result(mysql);if(res == NULL){mysql_close(mysql);return -1;}//7.获取结果集中的结果条数// int mysql_num_rows(MYSQL_RES * res)// int mysql_num_fields(MYSQL_RES * res)int num_row = mysql_num_rows(res);int num_col = mysql_num_fields(res);//8.遍历保存到本地的结果集for(int i=0;i<num_row;i++){//MYSQL_ROW mysql_fetch_row(MYSQL_RES * res)MYSQL_ROW row = mysql_fetch_row(res);//就理解为这是一个数组for(int j=0;j<num_col;j++){printf("%s\t",row[j]);}printf("\n");}//9.释放结果集mysql_free_result(res);//10.关闭数据库mysql_close(mysql);return 0;
}
- 查询成功!!!!!
4.前端内容的了解
1.HTML 结构
1.认识 HTML 标签
2.HTML 文件基本结构
3.HTML 常见标签
1.注释标签
2.标题标签: h1-h6
3.段落标签与行标签
段落标签: p:p与/p之间的内容会被单独设置为一个段落
换行标签: br
4.文本格式化标签
5.图片标签!!!!!!!十分重要(单标签)
1.简单结构
- 这些属性必须要写在《img》标签里面!!!!!
6.超链接标签!!!!!!!也十分重要(双标签)
《a》《/a》
- target可以用来设置是否需要重新开一个网页!!!!
7.表端标签!!!!!!!也十分重要(双标签)
先由《form》《/form》形成表端域
,然后在这两个标签之间就可以进行表的书写
1.form标签:
action=“”中的内容就是我们要提交的服务器地址!!!!!!
2.input标签:
- 还记得第一节里写的wserver吗,我们把他运行起来 ./wserver,然后点击提交按钮
- 服务器相应对应的请求,返回内容
对应的服务器也得到了对应的数据
用户名和密码,服务器都已经得知!!!!
<html><head><meta charset='utf-8'><title> 测试 </title></head><body><h1>Hello World</h1><p>在css中我们一般使用px作为单位,</p>在桌面浏览器中css的1个像素往往都是对应着电脑屏幕的1个物理像素,这可能会造成我们的一个错觉<br>,那就是css中的像素就是设备的物理像素。<br><img src="./OIP-C.jpg"><a href="https://www.baidu.com"> 这是一个连接,可以跳转到百度 </a><form action='http://115.120.238.130:8081/login'method="post"><input type="text" name="username"><input type="password" name="password"><input type="submit" name="submit" value="提交"></form></body>
</html>
2.CSS 结构
1.基本语法规范
选择器+声明!!!!
- style标签
需要放到head标签里面去
才能发挥作用
2.选择器介绍
参考文档
这里着重介绍一下类选择器:
- 多个标签可以设置为同一个类型,然后对这些标签内容做统一处理!!!
这里着重介绍一下id选择器:
这里着重介绍一下通配符*选择器:
3.Javascript 结构
学习目的:
1.给按钮添加事件
- 如上文,设置完后,点击按钮会发出弹窗!!!!!
2.设置一个页面控件
(1)修改页面的内容
点击按钮后:
(2)在输入框中输入内容并引起反馈
4.AJAX 结构(jequery)
测试目的:建立ajax请求,我们在网页输入框中输入username和password,然后点击按钮,在服务器上要有显示!!!!!!!!
1.jequery安装
成功在服务器上面获取我们在网页上输入的内容!!!!!!!!
5.websocket 结构
测试目的:在我们刚刚写的html中向服务端发送websocket请求而不是ajax请求,从输入框中获取数据,发送给服务器,得到相应后,返回内容到html网页中,展示出来!!!!!!!!!!!!!!
输入111,点击按钮---------------------------------------------------
- 内容被改变了!!!!!!!!!!!!!