위 챗 애플 릿 이 실시 간 통신 채 팅 기능 을 실현 하 는 인 스 턴 스 코드

프로젝트 배경:애플 릿 에서 실시 간 채 팅 기능 구현
서버 도 메 인 이름 설정
프로 세 스 설정

참고 URL 설정:https://developers.weixin.qq.com/miniprogram/dev/api/api-network.html
2.nginx 에서 역방향 프 록 시 암호 화 웹 소켓(ws)설정

upstream websocket{
 hash $remote_addr consistent;
 server 127.0.0.1:9090 weight=5 max_fails=3 fail_timeout=30s;
}
server {
 listen 80;
 server_name www.xxxx.cn;
 rewrite ^(.*)$ https://$host$1 permanent;
}
server
 { 
 listen 443;
  server_name www.xxxx.cn;
  ssl on;
  root /home/wwwroot/yzcp;
  index index.php index.html index.htm;
  ssl_certificate /usr/local/nginx/conf/cert/1526060965511.pem;#          
  ssl_certificate_key /usr/local/nginx/conf/cert/1526060965511.key;#       
  ssl_session_timeout 5m;
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  ssl_verify_client off;
 #  index.php
  location / {
 #index index.php;
 deny 127.0.0.1;
   if (!-e $request_filename) {
    #    
    rewrite ^(.*)$ /index.php?s=$1 last;
    break;
   }
   #wss  
   client_max_body_size 100m;
   proxy_redirect off;
   proxy_pass http://websocket;#        
   proxy_set_header Host $host;# http       
   proxy_set_header X-Real-IP $remote_addr;#     IP  
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;#           IP  
   proxy_read_timeout 604800s;#websocket    ,   60s
   proxy_http_version 1.1;
   proxy_set_header Upgrade $http_upgrade;
   proxy_set_header Connection "Upgrade";
  }
  location ~ .+\.php {
   fastcgi_pass unix:/tmp/php-cgi.sock;
   fastcgi_index index.php;
   include fastcgi_params;
   set $path_info "";
   set $real_script_name $fastcgi_script_name;
    if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") {
    set $real_script_name $1;
    set $path_info $2;
   }
   fastcgi_param SCRIPT_FILENAME $document_root$real_script_name;
   fastcgi_param SCRIPT_NAME $real_script_name;
   fastcgi_param PATH_INFO $path_info;
  }
 
  #     
  location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
 {
 expires  30d;
 }
 location ~ .*\.(js|css)?$
 {
 expires  12h;
 }
 access_log /home/wwwlogs/www1537ucn.log;
 }
3.swoole 설치
컴 파일 설치:

wget http://pecl.php.net/get/swoole-1.9.3.tgz  //  swoole 
tar -zvxf swoole-1.9.3.tgz  //  swoole
cd swoole-1.9.3/;  //  swoole
/usr/local/php54/bin/phpize;  //  configure
./configure --with-php-config=/usr/local/php/bin/php-config
make && make install   //  
cd /phpstudy/server/php/lib/php/extensions/no-debug-non-zts-20121212 //        swoole.so (  :             )
vim /phpstudy/server/php/etc/php.ini  // php.ini  extension=swoole.so         
lnmp restart; //  nginx 
php -m; //  phpinfo,   swoole       
4.서버 쪽 실행 프로그램
1.server.php 를 프로젝트 의 루트 디 렉 터 리 에 만 들 면 됩 니 다.

<?php
//     swoole websocket       9501  
$server = new swoole_websocket_server("   IP", 9090);
//         ip   。  ip   127.0.0.1,                ,         。
//       9090,    netstat           。        ,        , 9502,9503 。
$server->on('open', function (swoole_websocket_server $server, $request) {
 echo "      {$request->fd}
"; }); $server->on('message', function (swoole_websocket_server $server, $frame) { foreach($server->connections as $key => $fd) { $user_message = $frame->data; $server->push($fd, $user_message); } }); $server->on('close', function ($ser, $fd) { echo "client {$fd} closed
"; }); $server->start(); ?>
2、swoole 때문에server 는 CLI 모드 에서 만 실 행 될 수 있 으 므 로 브 라 우 저 를 통 해 접근 하려 고 하지 마 십시오.이것 은 잘못 되 었 습 니 다.명령 행 아래 에서 실 행 됩 니 다.phop 의 절대 경 로 를 찾 아야 합 니 다.  server.php  (이 코드 는 서버 에서 프로그램 을 뛰 어 다 니 라 는 뜻 이다)
메모:php server.php명령 이 실 행 된 후 아래 의 검 은 상자 가 닫 히 면 채 팅 을 할 수 없습니다.그래서 일반 사용 명령:nohup php server.php &
5.클 라 이언 트
1.웹 페이지 코드

<!DOCTYPE html>
<html>
<head>
 <meta charset="utf-8">
 <title>  </title>
 <style type="text/css">
  #show{
   width: 600px;
   height: 300px;
   overflow-y: scroll;
  }
  .my-message{
   background-color: rgba(105, 105, 105, 0.64);
   color: #9e0505;
   width: 200px;
   float: right;
   padding: 10px;
  }
  .other-message{
   background-color: rgba(105, 105, 105, 0.64);
   color: #9e0505;
   width: 200px;
   float: left;
   padding: 10px;
  }
 </style>
</head>
<body>
 <div id="show"></div>
 <div class="panel">
    :<textarea id="content"></textarea>
     :<input type="text" id="touser">
  <input type="button" id="send-btn" value="  ">
  <input type="button" id="close-btn" value="  ">
 </div>
</body>
<script src="__PUBLIC__/js/jquery-1.10.2.min.js" charset="utf-8"></script>
<script type="text/javascript">
 var socket = new WebSocket("wss://  ");
 $("#close-btn").click(function () {
  socket.close();
 })
 $("#send-btn").click(function () {
  var touser = $("#touser").val();
  var content = $("#content").val();
  var htmlstr = "<div><p class='my-message'> :"+content+"</p></div>";
  $("#show").append(htmlstr);
  socket.send(content+"@"+touser);
 })
 socket.onmessage = function (p1) {
  var htmlstr = "<div><p class='other-message'>"+p1.data+"</p></div>";
  $("#show").append(htmlstr);
 }
</script>
</html>
2.애플 릿 엔 드 의 코드
Uitls/websocket.js:

var url = 'wss://www.xxx.cn';//     
function connect(user, func) {
 wx.connectSocket({
 url: url,
 header: { 'content-type': 'application/json' },
 success: function () {
  console.log('websocket    ~')
 },
 fail: function () {
  console.log('websocket    ~')
 }
 })
 wx.onSocketOpen(function (res) {
 wx.showToast({
  title: 'websocket   ~',
  icon: "success",
  duration: 2000
 })
 //       
 wx.onSocketMessage(func);//func              
 });
 wx.onSocketError(function (res) {
 wx.showToast({
  title: 'websocket    ,   !',
  icon: "none",
  duration: 2000
 })
 })
}
//    
function send(msg) {
 wx.sendSocketMessage({
 data: msg
 });
}
module.exports = {
 connect: connect,
 send: send
}
JS:

// pages/socks/socks.js
const app = getApp()
var websocket = require('../../utils/websocket.js');
var utils = require('../../utils/util.js');
Page({
 /**
 *        
 */
 data: {
 newslist: [],
 userInfo: {},
 scrollTop: 0,
 increase: false,//        
 aniStyle: true,//    
 message: "",
 previewImgList: []
 },
 /**
 *       --      
 */
 onLoad: function () {
 var that = this
 if (app.globalData.userInfo) {
  this.setData({
  userInfo: app.globalData.userInfo
  })
 }
 //    
 websocket.connect(this.data.userInfo, function (res) {
  // console.log(JSON.parse(res.data))
  var list = []
  list = that.data.newslist
  list.push(JSON.parse(res.data))
  that.setData({
  newslist: list
  })
 })
 },
 //     
 onUnload() {
 wx.closeSocket();
 wx.showToast({
  title: '     ~',
  icon: "none",
  duration: 2000
 })
 },
 //      
 send: function () {
 var flag = this
 if (this.data.message.trim() == "") {
  wx.showToast({
  title: '       ~',
  icon: "none",
  duration: 2000
  })
 } else {
  setTimeout(function () {
  flag.setData({
   increase: false
  })
  }, 500)
  websocket.send('{ "content": "' + this.data.message + '", "date": "' + utils.formatTime(new Date()) + '","type":"text", "nickName": "' + this.data.userInfo.nickName + '", "avatarUrl": "' + this.data.userInfo.avatarUrl + '" }')
  this.bottom()
 }
 },
 //  input    
 bindChange(res) {
 this.setData({
  message: res.detail.value
 })
 },
 cleanInput() {
 //button     ,                   input 
 this.setData({
  message: this.data.message
 })
 },
 increase() {
 this.setData({
  increase: true,
  aniStyle: true
 })
 },
 //      message   
 outbtn() {
 this.setData({
  increase: false,
  aniStyle: true
 })
 },
 //    
 chooseImage() {
 var that = this
 wx.chooseImage({
  count: 1, //   9
  sizeType: ['original', 'compressed'], //             ,      
  sourceType: ['album', 'camera'], //              ,      
  success: function (res) {
  //                ,tempFilePath    img   src      
  var tempFilePaths = res.tempFilePaths
  // console.log(tempFilePaths)
  wx.uploadFile({
   url: 'wss://www.xxx.cn', //     
   filePath: tempFilePaths[0],
   name: 'file',
   headers: {
   'Content-Type': 'form-data'
   },
   success: function (res) {
   if (res.data) {
    that.setData({
    increase: false
    })
    websocket.send('{"images":"' + res.data + '","date":"' + utils.formatTime(new Date()) + '","type":"image","nickName":"' + that.data.userInfo.nickName + '","avatarUrl":"' + that.data.userInfo.avatarUrl + '"}')
    that.bottom()
   }
   }
  })
  }
 })
 },
 //    
 previewImg(e) {
 var that = this
 //      wxml image    data-set=“    ”,      
 var res = e.target.dataset.src
 var list = this.data.previewImgList //         
 //  res        ,    push    , -1  res   
 if (list.indexOf(res) == -1) {
  this.data.previewImgList.push(res)
 }
 wx.previewImage({
  current: res, //        http  
  urls: that.data.previewImgList //        http    
 })
 },
 //           
 bottom: function () {
 var query = wx.createSelectorQuery()
 query.select('#flag').boundingClientRect()
 query.selectViewport().scrollOffset()
 query.exec(function (res) {
  wx.pageScrollTo({
  scrollTop: res[0].bottom // #the-id        
  })
  res[1].scrollTop //            
 })
 },
})
WXML:

<!--pages/socks/socks.wxml-->
<view class="news" bindtap='outbtn'>
<view class="chat-notice" wx:if="{{userInfo}}">    :    {{ userInfo.nickName }}      </view>
<view class="historycon">
<scroll-view scroll-y="true" class="history" scroll-top="{{scrollTop}}">
<block wx:for="{{newslist}}" wx:key>
 <!--      -->
<!-- <view class="chat-news">
<view style="text-align: left;padding-left: 20rpx;">
<image class='new_img' src="{{item.avatarUrl? item.avatarUrl:'images/avator.png'}}"></image>
<text class="name">{{ item.nickName }}{{item.date}}</text>
</view>
<view class='you_left'>
<block wx:if="{{item.type=='text'}}">
<view class='new_txt'>{{item.content}}</view>
</block>
<block wx:if="{{item.type=='image'}}">
<image class="selectImg" src="{{item.images}}"></image>
</block>
</view>
</view> -->
<view>{{item.date}}</view>
<!--      -->
<view class="chat-news" wx:if="{{item.nickName == userInfo.nickName}}">
<view style="text-align: right;padding-right: 20rpx;">
<text class="name">{{ item.nickName }}</text>
<image class='new_img' src="{{userInfo.avatarUrl}}"></image>
</view>
<view class='my_right'>
<block wx:if="{{item.type=='text'}}">
<view class='new_txt'>{{item.content}}</view>
</block>
<block wx:if="{{item.type=='image'}}">
<image class="selectImg" src="{{item.images}}" data-src="{{item.images}}" lazy-load="true" bindtap="previewImg"></image>
</block>
</view>
</view>
<!--       -->
<view class="chat-news" wx:else>
<view style="text-align: left;padding-left: 20rpx;">
<image class='new_img' src="{{item.avatarUrl? item.avatarUrl:'images/avator.png'}}"></image>
<text class="name">{{ item.nickName }}</text>
</view>
<view class='you_left'>
<block wx:if="{{item.type=='text'}}">
<view class='new_txt'>{{item.content}}</view>
</block>
<block wx:if="{{item.type=='image'}}">
<image class="selectImg" src="{{item.images}}" data-src="{{item.images}}" lazy-load="true" bindtap="previewImg"></image>
</block>
</view>
</view>
</block>
</scroll-view>
</view>
</view>
<view id="flag"></view>
<!--      -->
<view class="message">
<form bindreset="cleanInput" class="sendMessage">
<input type="text" placeholder="       .." value="{{massage}}" bindinput='bindChange'></input>
<view class="add" bindtap='increase'>+</view>
<button type="primary" bindtap='send' formType="reset" size="small" button-hover="blue">  </button>
</form>
<view class='increased {{aniStyle?"slideup":"slidedown"}}' wx:if="{{increase}}">
<view class="image" bindtap='chooseImage'>   </view>
</view>
</view>
WXSS:

/* pages/socks/socks.wxss */
page {
background-color: #f7f7f7;
height: 100%;
}
/*      */
.news {
padding-top: 30rpx;
text-align: center;
/* height:100%; */
box-sizing:border-box;
}
#flag{
margin-bottom: 100rpx;
height: 30rpx;
}
.chat-notice{
text-align: center;
font-size: 30rpx;
padding: 10rpx 0;
color: #666;
}
.historycon {
height: 100%;
width: 100%;
/* flex-direction: column; */
display: flex;
border-top: 0px;
}
/*    */
.chat-news{
width: 100%;
overflow: hidden;
}
.chat-news .my_right {
float: right;
/* right: 40rpx; */
padding: 10rpx 10rpx;
}
.chat-news .name{
margin-right: 10rpx;
}
.chat-news .you_left {
float: left;
/* left: 5rpx; */
padding: 10rpx 10rpx;
}
.selectImg{
display: inline-block;
width: 150rpx;
height: 150rpx;
margin-left: 50rpx;
}
.my_right .selectImg{
margin-right: 80rpx;
}
.new_img {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
vertical-align: middle;
margin-right: 10rpx;
}
.new_txt {
max-width: 300rpx;
display: inline-block;
border-radius: 6rpx;
line-height: 60rpx;
background-color: #95d4ff;
padding: 5rpx 20rpx;
margin: 0 10rpx;
margin-left: 50rpx;
}
.my_right .new_txt{
margin-right:60rpx;
}
.you{
background-color: lightgreen;
}
.my {
border-color: transparent transparent transparent #95d4ff;
}
.you {
border-color: transparent #95d4ff transparent transparent;
}
.hei{
margin-top: 50px;
height: 20rpx;
}
.history {
height: 100%;
margin-top: 15px;
padding: 10rpx;
font-size: 14px;
line-height: 40px;
word-break: break-all;
}
::-webkit-scrollbar {
width: 0;
height: 0;
color: transparent;
z-index: -1;
}
/*        */
.message{
position: fixed;
bottom:0;
width: 100%;
}
.sendMessage{
display: block;
height: 80rpx;
padding: 10rpx 10rpx;
background-color: #fff;
border-top: 2rpx solid #eee;
border-bottom: 2rpx solid #eee;
z-index:3;
}
.sendMessage input{
float:left;
width: 66%;
height: 100%;
line-height: 80rpx;
border-bottom: 1rpx solid #ccc;
padding:0 10rpx;
font-size: 35rpx;
color: #666;
}
.sendMessage view{
display: inline-block;
width: 80rpx;
height: 80rpx;
line-height: 80rpx;
font-size: 60rpx;
text-align: center;
color: #999;
border: 1rpx solid #ccc;
border-radius: 50%;
margin-left: 10rpx;
}
.sendMessage button {
float: right;
font-size: 35rpx;
}
.increased{
width:100%;
/* height: 150rpx; */
padding: 40rpx 30rpx;
background-color: #fff;
}
.increased .image{
width: 100rpx;
height: 100rpx;
border: 3rpx solid #ccc;
line-height: 100rpx;
text-align: center;
border-radius: 8rpx;
font-size:35rpx;
}
@keyframes slidedown {
from {
transform: translateY(0);
}
to {
transform: translateY(100%);
}
}
.slidedown {
animation: slidedown 0.5s linear ;
}
.slideup {
animation: slideup 0.5s linear ;
}
@keyframes slideup {
from {
transform: translateY(100%);
}
to {
transform: translateY(0);
}
}
총결산
위 에서 말 한 것 은 소 편 이 여러분 에 게 소개 한 위 챗 애플 릿 이 실시 간 통신 채 팅 기능 을 실현 하 는 인 스 턴 스 코드 입 니 다.여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 저 에 게 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기