How do I close Vim externally?

Let's say I have a X11 server that's hanging, keeping me from saving the work from the XTerm Vim session that X11 server controls. (Not GVim, just regular Vim-in-XTerm.)
Is there a way that I could (from a different terminal) tell the running Vim process to "save all & exit" from the command line? By sending a signal, or through some other means?
I know about Vim swap files, and that I could just kill Vim and recover from the swap. I am asking if there is a "cleaner" way.

Having recently run into this problem (via another way: Vim running on a remote server, and I'd forgotten screen), I decided to hunt for a way.
The first idea was to look up the file descriptors used by Vim and try writing to it. Vim's fds point to the psedoterminal opened by the terminal emulator, naturally enough:
$ ls -l /proc/$(pgrep -n vim)/fd/
total 0
lrwx------ 1 muru muru 64 Nov 17 01:25 0 -> /dev/pts/14
lrwx------ 1 muru muru 64 Nov 17 01:25 1 -> /dev/pts/14
lrwx------ 1 muru muru 64 Nov 17 01:25 2 -> /dev/pts/14
lrwx------ 1 muru muru 64 Nov 17 01:25 3 -> socket:[99564312]

However, my initial few attempts failed:
echo '^[:wq^M' > /proc/$(pgrep -n vim)/fd/0
echo ':wq^M' > /proc/$(pgrep -n vim)/fd/0
echo ':wq^M' > /proc/$(pgrep -n vim)/fd/0
echo '^C' > /proc/$(pgrep -n vim)/fd/0
printf "%s" '^[:wqa!^M' > /proc/$(pgrep -n vim)/fd/0

The ^[ and ^M were obtained by CtrlVEsc and CtrlVEnter, respectively.
They all resulted in the characters showing up on the terminal (I was testing this out locally, before applying it to the remote session). Googling around, I found this SO post, using Python to write to the pseudoterminal device:
#!/usr/bin/python

import sys,os,fcntl,termios
if len(sys.argv) != 3:
   sys.stderr.write("usage: ttyexec.py tty command\n")
   sys.exit(1)
fd = os.open("/dev/" + sys.argv[1], os.O_RDWR)
cmd=sys.argv[2]
for i in range(len(cmd)):
   fcntl.ioctl(fd, termios.TIOCSTI, cmd[i])
fcntl.ioctl(fd, termios.TIOCSTI, '\n')
os.close(fd)

And trying it out on an interactive python shell worked:
$ sudo python3
Python 3.5.0 (default, Sep 20 2015, 11:28:25) 
[GCC 5.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os, fcntl, termios
>>> fd = os.open('/dev/pts/14', os.O_RDWR)
>>> a = '\033:wqa!\n'
>>> for i in a: fcntl.ioctl(fd, termios.TIOCSTI, i);
... 
b'\x1b'
b':'
b'w'
b'q'
b'a'
b'!'
b'\n'
>>> 

Done!

You can send commands to vim externally if you're running...
Vim servers
For example, doing:
vim --servername vim

will cause vim to launch a server with the name "vim". Call it twice and the new server will be called "vim1", call it thrice and it will be "vim2", etc. You might want to make an alias of that command.
You can know what server a particular instance is named by looking at the window title. When you see:

[No Name] + - VIM3

the server name is case-insensitively "VIM3" ("vim3" would refer to the same instance.). Note that if you see:

[No Name] + - VIM

that doesn't necessarily mean that it's got a server named "VIM". You can make sure the server exists by listing the server names with:
vim --serverlist

Still, the question only arises for "VIM", specifically. If you see "GVIM" or some other name with a number appended to it, then it does mean it's a server.
How to use client
Now, onto your question, you can save all and quit a given vim instance by doing, e.g.:
vim --servername vim2 --remote-send $'\e:wqa\n'

We use the escape to return to normal mode in case you're in insert or command mode. You can do something other than :wqa, but that seems the most appropriate to me because it will leave the swapfiles of buffers that could not be saved (because they're new and don't have a filename, etc.).
If you want to do so for all instances like in your case here, you can just loop through the server list like so:
for instance in $(vim --serverlist); do
  vim --servername $instance --remote-send $'\e:wqa\n'
done

If for some reason you don't like --remote-send, you can instead use --remote-expr which has the advantage that it will cause the client to output the result or the error that it might have caused, like so:
$ vim --servername vim2 --remote-expr 'execute("wqa")'

E141: No file name for buffer 1

Note that using Vim's server functionality requires that Vim was built with the +clientserver option.

Install the reptyr command using the system's package manager, such as:
sudo apt install reptyr
pacman -Sy reptyr

Then use the reptyr command to switch the remote tty to the local (new) tty, as follows:
ssh user@remote-hostname
ps auxw | grep -i vim
reptyr PID

Where PID is the process ID from the ps command output.
Upon the error:

Unable to attach to pid 12345: Permission denied

Change the "ptrace scope" to 0:
sudo su -
echo 0 > /proc/sys/kernel/yama/ptrace_scope

Once the vim session has been swapped from the old session to the new one, save and quit as usual. Note that you may have to press Enter to refresh the console.